calculator.c
author Ryan C. Gordon <icculus@icculus.org>
Mon, 08 Feb 2010 23:51:32 -0500
branchcalculator-experiment
changeset 823 48757134a880
parent 822 fa78ed1fe469
child 825 1ec9b7cc9434
permissions -rw-r--r--
Cleaned up TokenData FIXMEs, and added string cache.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
#define __MOJOSHADER_INTERNAL__ 1
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
#include "mojoshader_internal.h"
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
#if DEBUG_COMPILER_PARSER
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
#define LEMON_SUPPORT_TRACING 1
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     6
#endif
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
     8
typedef union TokenData
816
dd3e3e03b7ce Fixed literal data getting through the parser in one piece.
Ryan C. Gordon <icculus@icculus.org>
parents: 815
diff changeset
     9
{
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    10
    int64 i64;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    11
    double dbl;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    12
    const char *string;
816
dd3e3e03b7ce Fixed literal data getting through the parser in one piece.
Ryan C. Gordon <icculus@icculus.org>
parents: 815
diff changeset
    13
} TokenData;
dd3e3e03b7ce Fixed literal data getting through the parser in one piece.
Ryan C. Gordon <icculus@icculus.org>
parents: 815
diff changeset
    14
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    15
typedef struct StringBucket
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    16
{
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    17
    char *string;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    18
    struct StringBucket *next;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    19
} StringBucket;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    20
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    21
typedef struct Context
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    22
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    23
    int isfail;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    24
    int out_of_memory;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    25
    MOJOSHADER_malloc malloc;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    26
    MOJOSHADER_free free;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    27
    void *malloc_data;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    28
    int error_count;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    29
    ErrorList *errors;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    30
    Preprocessor *preprocessor;
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    31
    StringBucket *string_hashtable[256];
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
    32
    // !!! FIXME: do these really need to be in here?
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    33
    const char *token;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    34
    unsigned int tokenlen;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    35
    Token tokenval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    36
    unsigned int parse_errors;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
} Context;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    38
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    39
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    40
// Convenience functions for allocators...
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    41
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    42
static inline void out_of_memory(Context *ctx)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    43
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    44
    ctx->isfail = ctx->out_of_memory = 1;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    45
} // out_of_memory
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    46
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    47
static inline void *Malloc(Context *ctx, const size_t len)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    48
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
    void *retval = ctx->malloc((int) len, ctx->malloc_data);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
    if (retval == NULL)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    51
        out_of_memory(ctx);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
    return retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
} // Malloc
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    54
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    55
static inline char *StrDup(Context *ctx, const char *str)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    56
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    57
    char *retval = (char *) Malloc(ctx, strlen(str) + 1);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    58
    if (retval != NULL)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    59
        strcpy(retval, str);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    60
    return retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    61
} // StrDup
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    62
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
static inline void Free(Context *ctx, void *ptr)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    64
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    65
    if (ptr != NULL)  // check for NULL in case of dumb free() impl.
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    66
        ctx->free(ptr, ctx->malloc_data);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    67
} // Free
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    69
typedef enum Operator
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
{
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
    71
    OP_START_RANGE_UNARY,
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    72
    OP_POSTINCREMENT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    73
    OP_POSTDECREMENT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
    OP_PREINCREMENT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    75
    OP_PREDECREMENT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
    OP_NEGATE,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
    OP_COMPLEMENT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
    OP_NOT,
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
    79
    OP_END_RANGE_UNARY,
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
    80
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
    81
    OP_START_RANGE_BINARY,
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
    82
    OP_DEREF_ARRAY,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
    83
    OP_CALLFUNC,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
    84
    OP_DEREF_STRUCT,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
    85
    OP_COMMA,
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    86
    OP_MULTIPLY,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    87
    OP_DIVIDE,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
    OP_MODULO,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    89
    OP_ADD,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
    OP_SUBTRACT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    91
    OP_LSHIFT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
    OP_RSHIFT,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
    OP_LESSTHAN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    94
    OP_GREATERTHAN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
    OP_LESSTHANOREQUAL,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    96
    OP_GREATERTHANOREQUAL,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    97
    OP_EQUAL,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
    OP_NOTEQUAL,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    99
    OP_BINARYAND,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   100
    OP_BINARYXOR,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   101
    OP_BINARYOR,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   102
    OP_LOGICALAND,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   103
    OP_LOGICALOR,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
    OP_ASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   105
    OP_MULASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   106
    OP_DIVASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   107
    OP_MODASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   108
    OP_ADDASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   109
    OP_SUBASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   110
    OP_LSHIFTASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   111
    OP_RSHIFTASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   112
    OP_ANDASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   113
    OP_XORASSIGN,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   114
    OP_ORASSIGN,
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   115
    OP_END_RANGE_BINARY,
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   116
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   117
    OP_START_RANGE_TERNARY,
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   118
    OP_CONDITIONAL,
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   119
    OP_END_RANGE_TERNARY,
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   120
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   121
    OP_START_RANGE_DATA,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   122
    OP_IDENTIFIER,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   123
    OP_INT_LITERAL,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   124
    OP_FLOAT_LITERAL,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   125
    OP_STRING_LITERAL,
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   126
    OP_END_RANGE_DATA,
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   127
} Operator;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   128
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   129
static inline int operator_is_unary(const Operator op)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   130
{
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   131
    return ((op > OP_START_RANGE_UNARY) && (op < OP_END_RANGE_UNARY));
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   132
} // operator_is_unary
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   133
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   134
static inline int operator_is_binary(const Operator op)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   135
{
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   136
    return ((op > OP_START_RANGE_BINARY) && (op < OP_END_RANGE_BINARY));
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   137
} // operator_is_binary
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   138
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   139
static inline int operator_is_ternary(const Operator op)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   140
{
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   141
    return ((op > OP_START_RANGE_TERNARY) && (op < OP_END_RANGE_TERNARY));
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   142
} // operator_is_ternary
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   143
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   144
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   145
typedef struct Expression
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   146
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
    Operator op;  // operator
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   148
} Expression;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   149
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   150
#define NEW_EXPR(cls) \
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   151
    cls *retval = Malloc(ctx, sizeof (cls)); \
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   152
    if (retval == NULL) { return NULL; }
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   153
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   154
typedef struct ExpressionUnary
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   155
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   156
    Operator op;  // operator
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   157
    Expression *operand;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   158
} ExpressionUnary;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   159
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   160
typedef struct ExpressionBinary
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   161
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   162
    Operator op;  // operator
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   163
    Expression *left;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   164
    Expression *right;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   165
} ExpressionBinary;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   166
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   167
typedef struct ExpressionTernary
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   168
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   169
    Operator op;  // operator
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
    Expression *left;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   171
    Expression *center;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   172
    Expression *right;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   173
} ExpressionTernary;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   174
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   175
typedef struct ExpressionIdentifier
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   176
{
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   177
    Operator op;  // Always OP_IDENTIFIER
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   178
    const char *identifier;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   179
} ExpressionIdentifier;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   180
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   181
typedef struct ExpressionIntLiteral
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   182
{
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   183
    Operator op;  // Always OP_INT_LITERAL
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   184
    int64 value;
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   185
} ExpressionIntLiteral;
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   186
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   187
typedef struct ExpressionFloatLiteral
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   188
{
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   189
    Operator op;  // Always OP_FLOAT_LITERAL
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   190
    double value;
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   191
} ExpressionFloatLiteral;
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   192
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   193
typedef struct ExpressionStringLiteral
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   194
{
812
ac8e761569da Cleaned up operator enumeration, put it into ranges, fixed data ops.
Ryan C. Gordon <icculus@icculus.org>
parents: 811
diff changeset
   195
    Operator op;  // Always OP_STRING_LITERAL
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   196
    const char *string;
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   197
} ExpressionStringLiteral;
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   198
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   199
static Expression *new_unary_expr(Context *ctx, const Operator op,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   200
                                  Expression *operand)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   201
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   202
    NEW_EXPR(ExpressionUnary);
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   203
    assert(operator_is_unary(op));
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   204
    retval->op = op;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   205
    retval->operand = operand;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   206
    return (Expression *) retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   207
} // new_unary_expr
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   208
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   209
static Expression *new_binary_expr(Context *ctx, const Operator op,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   210
                                   Expression *left, Expression *right)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   211
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   212
    NEW_EXPR(ExpressionBinary);
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   213
    assert(operator_is_binary(op));
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   214
    retval->op = op;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   215
    retval->left = left;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   216
    retval->right = right;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   217
    return (Expression *) retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   218
} // new_binary_expr
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   219
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   220
static Expression *new_ternary_expr(Context *ctx, const Operator op,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   221
                                    Expression *left, Expression *center,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   222
                                    Expression *right)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   223
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   224
    NEW_EXPR(ExpressionTernary);
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   225
    assert(operator_is_ternary(op));
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   226
    retval->op = op;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   227
    retval->left = left;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   228
    retval->center = center;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   229
    retval->right = right;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   230
    return (Expression *) retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   231
} // new_ternary_expr
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   232
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   233
static Expression *new_identifier_expr(Context *ctx, const TokenData *data)
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   234
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   235
    NEW_EXPR(ExpressionIdentifier);
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   236
    retval->op = OP_IDENTIFIER;
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   237
    retval->identifier = data->string;  // cached; don't copy string.
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   238
    return (Expression *) retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   239
} // new_identifier_expr
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   240
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   241
static inline int64 strtoi64(const char *str, unsigned int len)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   242
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   243
    int64 retval = 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   244
    int64 mult = 1;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   245
    int i = 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   246
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   247
    while ((len) && (*str == ' '))
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   248
    {
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   249
        str++;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   250
        len--;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   251
    } // while
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   252
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   253
    if ((len) && (*str == '-'))
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   254
    {
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   255
        mult = -1;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   256
        str++;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   257
        len--;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   258
    } // if
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   259
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   260
    while (i < len)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   261
    {
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   262
        const char ch = str[i];
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   263
        if ((ch < '0') || (ch > '9'))
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   264
            break;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   265
        i++;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   266
    } // while
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   267
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   268
    while (--i >= 0)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   269
    {
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   270
        const char ch = str[i];
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   271
        retval += ((int64) (ch - '0')) * mult;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   272
        mult *= 10;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   273
    } // while
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   274
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   275
    return retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   276
} // strtoi64
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   277
816
dd3e3e03b7ce Fixed literal data getting through the parser in one piece.
Ryan C. Gordon <icculus@icculus.org>
parents: 815
diff changeset
   278
static Expression *new_literal_int_expr(Context *ctx, const TokenData *data)
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   279
{
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   280
    NEW_EXPR(ExpressionIntLiteral);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   281
    retval->op = OP_INT_LITERAL;
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   282
    retval->value = data->i64;
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   283
    return (Expression *) retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   284
} // new_literal_int_expr
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   285
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   286
static inline double strtodouble(const char *_str, unsigned int len)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   287
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   288
    // !!! FIXME: laziness prevails.
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   289
    char *str = (char *) alloca(len+1);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   290
    memcpy(str, _str, len);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   291
    str[len] = '\0';
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   292
    return strtod(str, NULL);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   293
} // strtodouble
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   294
816
dd3e3e03b7ce Fixed literal data getting through the parser in one piece.
Ryan C. Gordon <icculus@icculus.org>
parents: 815
diff changeset
   295
static Expression *new_literal_float_expr(Context *ctx, const TokenData *data)
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   296
{
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   297
    NEW_EXPR(ExpressionFloatLiteral);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   298
    retval->op = OP_FLOAT_LITERAL;
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   299
    retval->value = data->dbl;
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   300
    return (Expression *) retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   301
} // new_literal_float_expr
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   302
816
dd3e3e03b7ce Fixed literal data getting through the parser in one piece.
Ryan C. Gordon <icculus@icculus.org>
parents: 815
diff changeset
   303
static Expression *new_literal_string_expr(Context *ctx, const TokenData *data)
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   304
{
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   305
    NEW_EXPR(ExpressionStringLiteral);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   306
    retval->op = OP_STRING_LITERAL;
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   307
    retval->string = data->string;  // cached; don't copy string.
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   308
    return (Expression *) retval;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   309
} // new_string_literal_expr
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   310
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   311
static void print_expr(const Expression *expr, const int depth)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   312
{
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   313
    int i;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   314
    for (i = 0; i < depth; i++)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   315
        printf("    ");
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   316
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   317
    printf("Expression ");
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   318
    switch (expr->op)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   319
    {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   320
        #define PRINT_OP(op) case op: printf("%s\n", #op); break;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   321
        PRINT_OP(OP_DEREF_ARRAY);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   322
        PRINT_OP(OP_CALLFUNC);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   323
        PRINT_OP(OP_DEREF_STRUCT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   324
        PRINT_OP(OP_POSTINCREMENT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   325
        PRINT_OP(OP_POSTDECREMENT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   326
        PRINT_OP(OP_COMMA);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   327
        PRINT_OP(OP_PREINCREMENT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   328
        PRINT_OP(OP_PREDECREMENT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   329
        PRINT_OP(OP_NEGATE);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   330
        PRINT_OP(OP_COMPLEMENT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   331
        PRINT_OP(OP_NOT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   332
        PRINT_OP(OP_MULTIPLY);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   333
        PRINT_OP(OP_DIVIDE);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   334
        PRINT_OP(OP_MODULO);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   335
        PRINT_OP(OP_ADD);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   336
        PRINT_OP(OP_SUBTRACT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   337
        PRINT_OP(OP_LSHIFT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   338
        PRINT_OP(OP_RSHIFT);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   339
        PRINT_OP(OP_LESSTHAN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   340
        PRINT_OP(OP_GREATERTHAN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   341
        PRINT_OP(OP_LESSTHANOREQUAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   342
        PRINT_OP(OP_GREATERTHANOREQUAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   343
        PRINT_OP(OP_EQUAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   344
        PRINT_OP(OP_NOTEQUAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   345
        PRINT_OP(OP_BINARYAND);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   346
        PRINT_OP(OP_BINARYXOR);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   347
        PRINT_OP(OP_BINARYOR);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   348
        PRINT_OP(OP_LOGICALAND);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   349
        PRINT_OP(OP_LOGICALOR);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   350
        PRINT_OP(OP_CONDITIONAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   351
        PRINT_OP(OP_ASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   352
        PRINT_OP(OP_MULASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   353
        PRINT_OP(OP_DIVASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   354
        PRINT_OP(OP_MODASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   355
        PRINT_OP(OP_ADDASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   356
        PRINT_OP(OP_SUBASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   357
        PRINT_OP(OP_LSHIFTASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   358
        PRINT_OP(OP_RSHIFTASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   359
        PRINT_OP(OP_ANDASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   360
        PRINT_OP(OP_XORASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   361
        PRINT_OP(OP_ORASSIGN);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   362
        PRINT_OP(OP_INT_LITERAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   363
        PRINT_OP(OP_FLOAT_LITERAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   364
        PRINT_OP(OP_STRING_LITERAL);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   365
        PRINT_OP(OP_IDENTIFIER);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   366
        default: printf("---UNKNOWN!---\n"); return;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   367
    } // switch
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   368
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   369
    if (operator_is_unary(expr->op))
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   370
    {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   371
        const ExpressionUnary *unary = (const ExpressionUnary *) expr;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   372
        print_expr(unary->operand, depth + 1);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   373
    } // if
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   374
    else if (operator_is_binary(expr->op))
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   375
    {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   376
        const ExpressionBinary *binary = (const ExpressionBinary *) expr;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   377
        print_expr(binary->left, depth + 1);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   378
        print_expr(binary->right, depth + 1);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   379
    } // else if
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   380
    else if (operator_is_ternary(expr->op))
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   381
    {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   382
        const ExpressionTernary *ternary = (const ExpressionTernary *) expr;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   383
        print_expr(ternary->left, depth + 1);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   384
        print_expr(ternary->center, depth + 1);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   385
        print_expr(ternary->right, depth + 1);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   386
    } // else if
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   387
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   388
    else
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   389
    {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   390
        for (i = 0; i < (depth + 1); i++)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   391
            printf("    ");
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   392
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   393
        if (expr->op == OP_IDENTIFIER)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   394
        {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   395
            const ExpressionIdentifier *ident = (const ExpressionIdentifier *) expr;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   396
            printf("(%s)\n", ident->identifier);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   397
        } // if
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   398
        else if (expr->op == OP_INT_LITERAL)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   399
        {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   400
            const ExpressionIntLiteral *lit = (const ExpressionIntLiteral *) expr;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   401
            printf("(%lld)\n", (long long) lit->value);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   402
        } // if
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   403
        else if (expr->op == OP_FLOAT_LITERAL)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   404
        {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   405
            const ExpressionFloatLiteral *lit = (const ExpressionFloatLiteral *) expr;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   406
            printf("(%lf)\n", lit->value);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   407
        } // if
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   408
        else if (expr->op == OP_STRING_LITERAL)
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   409
        {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   410
            const ExpressionStringLiteral *lit = (const ExpressionStringLiteral *) expr;
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   411
            printf("(\"%s\")\n", lit->string);
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   412
        } // if
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   413
        else
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   414
        {
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   415
            assert(0 && "Shouldn't hit this.");
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   416
        } // else
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   417
    } // else
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   418
} // print_expr
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   419
821
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   420
static double run_expr(const Expression *expr)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   421
{
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   422
    if (operator_is_unary(expr->op))
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   423
    {
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   424
        const ExpressionUnary *unary = (const ExpressionUnary *) expr;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   425
        if (expr->op == OP_NEGATE)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   426
            return -run_expr(unary->operand);
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   427
        else if (expr->op == OP_COMPLEMENT)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   428
            return (double) (~((int64)run_expr(unary->operand)));
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   429
        else if (expr->op == OP_NOT)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   430
            return (run_expr(unary->operand) == 0.0) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   431
    } // if
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   432
    else if (operator_is_binary(expr->op))
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   433
    {
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   434
        const ExpressionBinary *binary = (const ExpressionBinary *) expr;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   435
        if (expr->op == OP_MULTIPLY)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   436
            return run_expr(binary->left) * run_expr(binary->right);
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   437
        else if (expr->op == OP_DIVIDE)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   438
            return run_expr(binary->left) / run_expr(binary->right);
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   439
        else if (expr->op == OP_ADD)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   440
            return run_expr(binary->left) + run_expr(binary->right);
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   441
        else if (expr->op == OP_SUBTRACT)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   442
            return run_expr(binary->left) - run_expr(binary->right);
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   443
        else if (expr->op == OP_LESSTHAN)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   444
            return (run_expr(binary->left) < run_expr(binary->right)) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   445
        else if (expr->op == OP_GREATERTHAN)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   446
            return (run_expr(binary->left) > run_expr(binary->right)) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   447
        else if (expr->op == OP_LESSTHANOREQUAL)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   448
            return (run_expr(binary->left) <= run_expr(binary->right)) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   449
        else if (expr->op == OP_GREATERTHANOREQUAL)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   450
            return (run_expr(binary->left) >= run_expr(binary->right)) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   451
        else if (expr->op == OP_EQUAL)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   452
            return (run_expr(binary->left) == run_expr(binary->right)) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   453
        else if (expr->op == OP_NOTEQUAL)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   454
            return (run_expr(binary->left) == run_expr(binary->right)) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   455
        else if (expr->op == OP_LOGICALAND)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   456
            return (((int64)run_expr(binary->left)) && ((int64)run_expr(binary->right))) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   457
        else if (expr->op == OP_LOGICALOR)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   458
            return (((int64)run_expr(binary->left)) || ((int64)run_expr(binary->right))) ? 1.0 : 0.0;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   459
        else if (expr->op == OP_BINARYAND)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   460
            return (double)(((int64)run_expr(binary->left)) & ((int64)run_expr(binary->right)));
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   461
        else if (expr->op == OP_BINARYOR)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   462
            return (double)(((int64)run_expr(binary->left)) | ((int64)run_expr(binary->right)));
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   463
        else if (expr->op == OP_BINARYXOR)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   464
            return (double)(((int64)run_expr(binary->left)) ^ ((int64)run_expr(binary->right)));
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   465
        else if (expr->op == OP_LSHIFT)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   466
            return (double)(((int64)run_expr(binary->left)) << ((int64)run_expr(binary->right)));
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   467
        else if (expr->op == OP_RSHIFT)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   468
            return (double)(((int64)run_expr(binary->left)) >> ((int64)run_expr(binary->right)));
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   469
        else if (expr->op == OP_MODULO)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   470
            return (double)(((int64)run_expr(binary->left)) % ((int64)run_expr(binary->right)));
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   471
    } // else if
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   472
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   473
    else if (operator_is_ternary(expr->op))
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   474
    {
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   475
        const ExpressionTernary *ternary = (const ExpressionTernary *) expr;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   476
        if (expr->op == OP_CONDITIONAL)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   477
            return (run_expr(ternary->left) != 0.0) ? run_expr(ternary->center) : run_expr(ternary->right);
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   478
    } // else if
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   479
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   480
    else
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   481
    {
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   482
        if (expr->op == OP_INT_LITERAL)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   483
        {
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   484
            const ExpressionIntLiteral *lit = (const ExpressionIntLiteral *) expr;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   485
            return ((double) lit->value);
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   486
        } // if
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   487
        else if (expr->op == OP_FLOAT_LITERAL)
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   488
        {
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   489
            const ExpressionFloatLiteral *lit = (const ExpressionFloatLiteral *) expr;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   490
            return lit->value;
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   491
        } // if
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   492
    } // else
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   493
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   494
    return 0.0;  // oh well.
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   495
} // run_expr
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   496
822
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   497
static void free_expr(Context *ctx, Expression *expr)
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   498
{
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   499
    if (operator_is_unary(expr->op))
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   500
    {
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   501
        const ExpressionUnary *unary = (const ExpressionUnary *) expr;
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   502
        free_expr(ctx, unary->operand);
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   503
    } // if
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   504
    else if (operator_is_binary(expr->op))
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   505
    {
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   506
        const ExpressionBinary *binary = (const ExpressionBinary *) expr;
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   507
        free_expr(ctx, binary->left);
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   508
        free_expr(ctx, binary->right);
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   509
    } // else if
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   510
    else if (operator_is_ternary(expr->op))
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   511
    {
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   512
        const ExpressionTernary *ternary = (const ExpressionTernary *) expr;
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   513
        free_expr(ctx, ternary->left);
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   514
        free_expr(ctx, ternary->center);
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   515
        free_expr(ctx, ternary->right);
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   516
    } // else if
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   517
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   518
    // don't need to free extra fields in other types at the moment.
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   519
822
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   520
    Free(ctx, expr);
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   521
} // free_expr
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   522
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   523
static void parse_complete(Context *ctx, Expression *expr)
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   524
{
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   525
    print_expr(expr, 0);
821
ecf9f8157ada Actually run the calculator, walking the parse tree.
Ryan C. Gordon <icculus@icculus.org>
parents: 820
diff changeset
   526
    printf("Result: %lf\n\n", run_expr(expr));
822
fa78ed1fe469 Free the parse tree once we're done with it.
Ryan C. Gordon <icculus@icculus.org>
parents: 821
diff changeset
   527
    free_expr(ctx, expr);
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   528
} // parse_complete
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   529
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   530
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   531
// !!! FIXME: sort of cut-and-paste from the preprocessor...
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   532
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   533
// this is djb's xor hashing function.
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   534
static inline uint32 hash_string_djbxor(const char *str, unsigned int len)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   535
{
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   536
    register uint32 hash = 5381;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   537
    while (len--)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   538
        hash = ((hash << 5) + hash) ^ *(str++);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   539
    return hash;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   540
} // hash_string_djbxor
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   541
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   542
static inline uint8 hash_string(const char *str, const unsigned int len)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   543
{
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   544
    return (uint8) hash_string_djbxor(str, len);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   545
} // hash_string
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   546
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   547
static const char *cache_string(Context *ctx, const char *str,
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   548
                                const unsigned int len)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   549
{
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   550
    const uint8 hash = hash_string(str, len);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   551
    StringBucket *bucket = ctx->string_hashtable[hash];
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   552
    StringBucket *prev = NULL;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   553
    while (bucket)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   554
    {
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   555
        const char *bstr = bucket->string;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   556
        if ((strncmp(bstr, str, len) == 0) && (bstr[len] == 0))
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   557
        {
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   558
            // Matched! Move this to the front of the list.
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   559
            if (prev != NULL)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   560
            {
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   561
                assert(prev->next == bucket);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   562
                prev->next = bucket->next;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   563
                bucket->next = ctx->string_hashtable[hash];
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   564
                ctx->string_hashtable[hash] = bucket;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   565
            } // if
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   566
            return bstr; // already cached
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   567
        } // if
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   568
        prev = bucket;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   569
        bucket = bucket->next;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   570
    } // while
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   571
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   572
    // no match, add to the table.
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   573
    bucket = (StringBucket *) Malloc(ctx, sizeof (StringBucket));
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   574
    if (bucket == NULL)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   575
        return NULL;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   576
    bucket->string = (char *) Malloc(ctx, len + 1);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   577
    if (bucket->string == NULL)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   578
    {
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   579
        Free(ctx, bucket);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   580
        return NULL;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   581
    } // if
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   582
    memcpy(bucket->string, str, len);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   583
    bucket->string[len] = '\0';
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   584
    bucket->next = ctx->string_hashtable[hash];
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   585
    ctx->string_hashtable[hash] = bucket;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   586
    return bucket->string;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   587
} // cache_string
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   588
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   589
static void free_string_cache(Context *ctx)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   590
{
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   591
    size_t i;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   592
    for (i = 0; i < STATICARRAYLEN(ctx->string_hashtable); i++)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   593
    {
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   594
        StringBucket *bucket = ctx->string_hashtable[i];
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   595
        ctx->string_hashtable[i] = NULL;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   596
        while (bucket)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   597
        {
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   598
            StringBucket *next = bucket->next;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   599
            Free(ctx, bucket->string);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   600
            Free(ctx, bucket);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   601
            bucket = next;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   602
        } // while
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   603
    } // for
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   604
} // free_string_cache
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   605
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   606
815
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   607
// This is where the actual parsing happens. It's Lemon-generated!
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   608
#define __MOJOSHADER_CALC_COMPILER__ 1
c999c015cdc0 Initial dumping of parse tree once parsing finishes.
Ryan C. Gordon <icculus@icculus.org>
parents: 814
diff changeset
   609
#include "calculator.h"
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   610
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   611
static int convert_to_lemon_token(const Context *ctx)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   612
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   613
    switch (ctx->tokenval)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   614
    {
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   615
        case ((Token) ','): return TOKEN_CALC_COMMA;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   616
        case ((Token) '='): return TOKEN_CALC_ASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   617
        case ((Token) TOKEN_ADDASSIGN): return TOKEN_CALC_ADDASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   618
        case ((Token) TOKEN_SUBASSIGN): return TOKEN_CALC_SUBASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   619
        case ((Token) TOKEN_MULTASSIGN): return TOKEN_CALC_MULASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   620
        case ((Token) TOKEN_DIVASSIGN): return TOKEN_CALC_DIVASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   621
        case ((Token) TOKEN_MODASSIGN): return TOKEN_CALC_MODASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   622
        case ((Token) TOKEN_LSHIFTASSIGN): return TOKEN_CALC_LSHIFTASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   623
        case ((Token) TOKEN_RSHIFTASSIGN): return TOKEN_CALC_RSHIFTASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   624
        case ((Token) TOKEN_ANDASSIGN): return TOKEN_CALC_ANDASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   625
        case ((Token) TOKEN_ORASSIGN): return TOKEN_CALC_ORASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   626
        case ((Token) TOKEN_XORASSIGN): return TOKEN_CALC_XORASSIGN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   627
        case ((Token) '?'): return TOKEN_CALC_QUESTION;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   628
        case ((Token) TOKEN_OROR): return TOKEN_CALC_OROR;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   629
        case ((Token) TOKEN_ANDAND): return TOKEN_CALC_ANDAND;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   630
        case ((Token) '|'): return TOKEN_CALC_OR;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   631
        case ((Token) '^'): return TOKEN_CALC_XOR;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   632
        case ((Token) '&'): return TOKEN_CALC_AND;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   633
        case ((Token) TOKEN_EQL): return TOKEN_CALC_EQL;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   634
        case ((Token) TOKEN_NEQ): return TOKEN_CALC_NEQ;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   635
        case ((Token) '<'): return TOKEN_CALC_LT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   636
        case ((Token) TOKEN_LEQ): return TOKEN_CALC_LEQ;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   637
        case ((Token) '>'): return TOKEN_CALC_GT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   638
        case ((Token) TOKEN_GEQ): return TOKEN_CALC_GEQ;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   639
        case ((Token) TOKEN_LSHIFT): return TOKEN_CALC_LSHIFT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   640
        case ((Token) TOKEN_RSHIFT): return TOKEN_CALC_RSHIFT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   641
        case ((Token) '+'): return TOKEN_CALC_PLUS;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   642
        case ((Token) '-'): return TOKEN_CALC_MINUS;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   643
        case ((Token) '*'): return TOKEN_CALC_STAR;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   644
        case ((Token) '/'): return TOKEN_CALC_SLASH;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   645
        case ((Token) '%'): return TOKEN_CALC_PERCENT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   646
        case ((Token) '!'): return TOKEN_CALC_EXCLAMATION;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   647
        case ((Token) '~'): return TOKEN_CALC_COMPLEMENT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   648
        case ((Token) TOKEN_DECREMENT): return TOKEN_CALC_MINUSMINUS;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   649
        case ((Token) TOKEN_INCREMENT): return TOKEN_CALC_PLUSPLUS;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   650
        case ((Token) '.'): return TOKEN_CALC_DOT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   651
        case ((Token) '['): return TOKEN_CALC_LBRACKET;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   652
        case ((Token) ']'): return TOKEN_CALC_RBRACKET;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   653
        case ((Token) '('): return TOKEN_CALC_LPAREN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   654
        case ((Token) ')'): return TOKEN_CALC_RPAREN;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   655
        case ((Token) TOKEN_INT_LITERAL): return TOKEN_CALC_INT_CONSTANT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   656
        case ((Token) TOKEN_FLOAT_LITERAL): return TOKEN_CALC_FLOAT_CONSTANT;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   657
        case ((Token) TOKEN_STRING_LITERAL): return TOKEN_CALC_STRING_LITERAL;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   658
        case ((Token) ':'): return TOKEN_CALC_COLON;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   659
        //case ((Token) ';'): return TOKEN_CALC_SEMICOLON;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   660
        //case ((Token) '{'): return TOKEN_CALC_LBRACE;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   661
        //case ((Token) '}'): return TOKEN_CALC_RBRACE;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   662
        case ((Token) TOKEN_IDENTIFIER): return TOKEN_CALC_IDENTIFIER;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   663
        case TOKEN_EOI: return 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   664
        case TOKEN_BAD_CHARS: printf("bad chars from lexer\n"); return 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   665
        case TOKEN_PREPROCESSING_ERROR: printf("error from lexer\n"); return 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   666
        default: assert(0 && "unexpected token from lexer\n"); return 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   667
    } // switch
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   668
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   669
    return 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   670
} // convert_to_lemon_token
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   671
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   672
static void MOJOSHADER_compile(const char *filename,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   673
                             const char *source, unsigned int sourcelen,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   674
                             const MOJOSHADER_preprocessorDefine *defines,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   675
                             unsigned int define_count,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   676
                             MOJOSHADER_includeOpen include_open,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   677
                             MOJOSHADER_includeClose include_close,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   678
                             MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   679
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   680
    Context ctx;
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   681
    TokenData data;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   682
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   683
    if (m == NULL) m = MOJOSHADER_internal_malloc;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   684
    if (f == NULL) f = MOJOSHADER_internal_free;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   685
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   686
    memset(&ctx, '\0', sizeof (Context));
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   687
    ctx.malloc = m;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   688
    ctx.free = f;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   689
    ctx.malloc_data = d;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   690
    ctx.preprocessor = preprocessor_start(filename, source, sourcelen,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   691
                                           include_open, include_close,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   692
                                           defines, define_count, 0, m, f, d);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   693
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   694
    void *pParser = ParseCalculatorAlloc(m, d);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   695
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   696
    #if DEBUG_COMPILER_PARSER
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   697
    ParseCalculatorTrace(stdout, "COMPILER: ");
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   698
    #endif
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   699
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   700
    do {
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   701
        ctx.token = preprocessor_nexttoken(ctx.preprocessor, &ctx.tokenlen,
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   702
                                           &ctx.tokenval);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   703
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   704
        const int lemon_token = convert_to_lemon_token(&ctx);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   705
        switch (lemon_token)
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   706
        {
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   707
            case TOKEN_CALC_INT_CONSTANT:
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   708
                data.i64 = strtoi64(ctx.token, ctx.tokenlen);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   709
                break;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   710
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   711
            case TOKEN_CALC_FLOAT_CONSTANT:
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   712
                data.dbl = strtodouble(ctx.token, ctx.tokenlen);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   713
                break;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   714
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   715
            case TOKEN_CALC_STRING_LITERAL:
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   716
            case TOKEN_CALC_IDENTIFIER:
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   717
                data.string = cache_string(&ctx, ctx.token, ctx.tokenlen);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   718
                break;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   719
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   720
            default:
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   721
                data.i64 = 0;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   722
                break;
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   723
        } // switch
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   724
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   725
        ParseCalculator(pParser, lemon_token, data, &ctx);
820
fd001ff71c65 Stop parsing if the parser panics.
Ryan C. Gordon <icculus@icculus.org>
parents: 818
diff changeset
   726
    } while ((!ctx.isfail) && (ctx.tokenval != TOKEN_EOI));
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   727
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   728
    ParseCalculatorFree(pParser, f, d);
823
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   729
    // !!! FIXME: destruct (ctx) here.
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   730
    free_string_cache(&ctx);
48757134a880 Cleaned up TokenData FIXMEs, and added string cache.
Ryan C. Gordon <icculus@icculus.org>
parents: 822
diff changeset
   731
} // MOJOSHADER_compile
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   732
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   733
int main(int argc, char **argv)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   734
{
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   735
    const char *ln;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   736
    size_t len = 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   737
    FILE *io = stdin;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   738
    const char *filename = "<stdin>";
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   739
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   740
    while ((ln = fgetln(io, &len)) != NULL)
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   741
    {
818
6f893a2224d8 Ignore blank lines.
Ryan C. Gordon <icculus@icculus.org>
parents: 817
diff changeset
   742
        if (len == 1)
6f893a2224d8 Ignore blank lines.
Ryan C. Gordon <icculus@icculus.org>
parents: 817
diff changeset
   743
            continue;
6f893a2224d8 Ignore blank lines.
Ryan C. Gordon <icculus@icculus.org>
parents: 817
diff changeset
   744
        else if ((len == 5) && (memcmp(ln, "quit\n", 5) == 0))
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   745
            break;
814
a2cf3f36ed1c Allow "q" to quit calculator, too.
Ryan C. Gordon <icculus@icculus.org>
parents: 812
diff changeset
   746
        else if ((len == 2) && (memcmp(ln, "q\n", 2) == 0))
a2cf3f36ed1c Allow "q" to quit calculator, too.
Ryan C. Gordon <icculus@icculus.org>
parents: 812
diff changeset
   747
            break;
811
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   748
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   749
        MOJOSHADER_compile(filename, ln, (unsigned int) len,
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   750
                           NULL, 0, NULL, NULL, NULL, NULL, NULL);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   751
    } // while
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   752
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   753
    fclose(io);
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   754
    return 0;
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   755
} // main
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   756
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   757
// end of calculator.c ...
307e3ab506fa Start of experiment with a basic calculator.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   758