Home | History | Annotate | Download | only in glsl
      1 /* -*- c++ -*- */
      2 /*
      3  * Copyright  2010 Intel Corporation
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #ifndef S_EXPRESSION_H
     26 #define S_EXPRESSION_H
     27 
     28 #include "main/core.h" /* for Elements */
     29 #include "util/strtod.h"
     30 #include "list.h"
     31 
     32 /* Type-safe downcasting macros (also safe to pass NULL) */
     33 #define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \
     34                                                            : NULL
     35 #define SX_AS_LIST(x)   SX_AS_(list, x)
     36 #define SX_AS_SYMBOL(x) SX_AS_(symbol, x)
     37 #define SX_AS_NUMBER(x) SX_AS_(number, x)
     38 #define SX_AS_INT(x)    SX_AS_(int, x)
     39 
     40 /* Pattern matching macros */
     41 #define MATCH(list, pat) s_match(list, ARRAY_SIZE(pat), pat, false)
     42 #define PARTIAL_MATCH(list, pat) s_match(list, ARRAY_SIZE(pat), pat, true)
     43 
     44 /* For our purposes, S-Expressions are:
     45  * - <int>
     46  * - <float>
     47  * - symbol
     48  * - (expr1 expr2 ... exprN)     where exprN is an S-Expression
     49  *
     50  * Unlike LISP/Scheme, we do not support (foo . bar) pairs.
     51  */
     52 class s_expression : public exec_node
     53 {
     54 public:
     55    /**
     56     * Read an S-Expression from the given string.
     57     * Advances the supplied pointer to just after the expression read.
     58     *
     59     * Any allocation will be performed with 'ctx' as the ralloc owner.
     60     */
     61    static s_expression *read_expression(void *ctx, const char *&src);
     62 
     63    /**
     64     * Print out an S-Expression.  Useful for debugging.
     65     */
     66    virtual void print() = 0;
     67 
     68    virtual bool is_list()   const { return false; }
     69    virtual bool is_symbol() const { return false; }
     70    virtual bool is_number() const { return false; }
     71    virtual bool is_int()    const { return false; }
     72 
     73 protected:
     74    s_expression() { }
     75 };
     76 
     77 /* Atoms */
     78 
     79 class s_number : public s_expression
     80 {
     81 public:
     82    bool is_number() const { return true; }
     83 
     84    virtual float fvalue() = 0;
     85 
     86 protected:
     87    s_number() { }
     88 };
     89 
     90 class s_int : public s_number
     91 {
     92 public:
     93    s_int(int x) : val(x) { }
     94 
     95    bool is_int() const { return true; }
     96 
     97    float fvalue() { return float(this->val); }
     98    int value() { return this->val; }
     99 
    100    void print();
    101 
    102 private:
    103    int val;
    104 };
    105 
    106 class s_float : public s_number
    107 {
    108 public:
    109    s_float(float x) : val(x) { }
    110 
    111    float fvalue() { return this->val; }
    112 
    113    void print();
    114 
    115 private:
    116    float val;
    117 };
    118 
    119 class s_symbol : public s_expression
    120 {
    121 public:
    122    s_symbol(const char *, size_t);
    123 
    124    bool is_symbol() const { return true; }
    125 
    126    const char *value() { return this->str; }
    127 
    128    void print();
    129 
    130 private:
    131    const char *str;
    132 };
    133 
    134 /* Lists of expressions: (expr1 ... exprN) */
    135 class s_list : public s_expression
    136 {
    137 public:
    138    s_list();
    139 
    140    virtual bool is_list() const { return true; }
    141 
    142    void print();
    143 
    144    exec_list subexpressions;
    145 };
    146 
    147 // ------------------------------------------------------------
    148 
    149 /**
    150  * Part of a pattern to match - essentially a record holding a pointer to the
    151  * storage for the component to match, along with the appropriate type.
    152  */
    153 class s_pattern {
    154 public:
    155    s_pattern(s_expression *&s) : p_expr(&s),   type(EXPR)   { }
    156    s_pattern(s_list       *&s) : p_list(&s),   type(LIST)   { }
    157    s_pattern(s_symbol     *&s) : p_symbol(&s), type(SYMBOL) { }
    158    s_pattern(s_number     *&s) : p_number(&s), type(NUMBER) { }
    159    s_pattern(s_int        *&s) : p_int(&s),    type(INT)    { }
    160    s_pattern(const char *str)  : literal(str), type(STRING) { }
    161 
    162    bool match(s_expression *expr);
    163 
    164 private:
    165    union {
    166       s_expression **p_expr;
    167       s_list       **p_list;
    168       s_symbol     **p_symbol;
    169       s_number     **p_number;
    170       s_int        **p_int;
    171       const char *literal;
    172    };
    173    enum { EXPR, LIST, SYMBOL, NUMBER, INT, STRING } type;
    174 };
    175 
    176 bool
    177 s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial);
    178 
    179 #endif /* S_EXPRESSION_H */
    180