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 #pragma once
     26 #ifndef S_EXPRESSION_H
     27 #define S_EXPRESSION_H
     28 
     29 #include "main/core.h" /* for Elements */
     30 #include "strtod.h"
     31 #include "list.h"
     32 
     33 /* Type-safe downcasting macros (also safe to pass NULL) */
     34 #define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \
     35                                                            : NULL
     36 #define SX_AS_LIST(x)   SX_AS_(list, x)
     37 #define SX_AS_SYMBOL(x) SX_AS_(symbol, x)
     38 #define SX_AS_NUMBER(x) SX_AS_(number, x)
     39 #define SX_AS_INT(x)    SX_AS_(int, x)
     40 
     41 /* Pattern matching macros */
     42 #define MATCH(list, pat) s_match(list, Elements(pat), pat, false)
     43 #define PARTIAL_MATCH(list, pat) s_match(list, Elements(pat), pat, true)
     44 
     45 /* For our purposes, S-Expressions are:
     46  * - <int>
     47  * - <float>
     48  * - symbol
     49  * - (expr1 expr2 ... exprN)     where exprN is an S-Expression
     50  *
     51  * Unlike LISP/Scheme, we do not support (foo . bar) pairs.
     52  */
     53 class s_expression : public exec_node
     54 {
     55 public:
     56    /**
     57     * Read an S-Expression from the given string.
     58     * Advances the supplied pointer to just after the expression read.
     59     *
     60     * Any allocation will be performed with 'ctx' as the ralloc owner.
     61     */
     62    static s_expression *read_expression(void *ctx, const char *&src);
     63 
     64    /**
     65     * Print out an S-Expression.  Useful for debugging.
     66     */
     67    virtual void print() = 0;
     68 
     69    virtual bool is_list()   const { return false; }
     70    virtual bool is_symbol() const { return false; }
     71    virtual bool is_number() const { return false; }
     72    virtual bool is_int()    const { return false; }
     73 
     74 protected:
     75    s_expression() { }
     76 };
     77 
     78 /* Atoms */
     79 
     80 class s_number : public s_expression
     81 {
     82 public:
     83    bool is_number() const { return true; }
     84 
     85    virtual float fvalue() = 0;
     86 
     87 protected:
     88    s_number() { }
     89 };
     90 
     91 class s_int : public s_number
     92 {
     93 public:
     94    s_int(int x) : val(x) { }
     95 
     96    bool is_int() const { return true; }
     97 
     98    float fvalue() { return float(this->val); }
     99    int value() { return this->val; }
    100 
    101    void print();
    102 
    103 private:
    104    int val;
    105 };
    106 
    107 class s_float : public s_number
    108 {
    109 public:
    110    s_float(float x) : val(x) { }
    111 
    112    float fvalue() { return this->val; }
    113 
    114    void print();
    115 
    116 private:
    117    float val;
    118 };
    119 
    120 class s_symbol : public s_expression
    121 {
    122 public:
    123    s_symbol(const char *, size_t);
    124 
    125    bool is_symbol() const { return true; }
    126 
    127    const char *value() { return this->str; }
    128 
    129    void print();
    130 
    131 private:
    132    const char *str;
    133 };
    134 
    135 /* Lists of expressions: (expr1 ... exprN) */
    136 class s_list : public s_expression
    137 {
    138 public:
    139    s_list();
    140 
    141    virtual bool is_list() const { return true; }
    142 
    143    void print();
    144 
    145    exec_list subexpressions;
    146 };
    147 
    148 // ------------------------------------------------------------
    149 
    150 /**
    151  * Part of a pattern to match - essentially a record holding a pointer to the
    152  * storage for the component to match, along with the appropriate type.
    153  */
    154 class s_pattern {
    155 public:
    156    s_pattern(s_expression *&s) : p_expr(&s),   type(EXPR)   { }
    157    s_pattern(s_list       *&s) : p_list(&s),   type(LIST)   { }
    158    s_pattern(s_symbol     *&s) : p_symbol(&s), type(SYMBOL) { }
    159    s_pattern(s_number     *&s) : p_number(&s), type(NUMBER) { }
    160    s_pattern(s_int        *&s) : p_int(&s),    type(INT)    { }
    161    s_pattern(const char *str)  : literal(str), type(STRING) { }
    162 
    163    bool match(s_expression *expr);
    164 
    165 private:
    166    union {
    167       s_expression **p_expr;
    168       s_list       **p_list;
    169       s_symbol     **p_symbol;
    170       s_number     **p_number;
    171       s_int        **p_int;
    172       const char *literal;
    173    };
    174    enum { EXPR, LIST, SYMBOL, NUMBER, INT, STRING } type;
    175 };
    176 
    177 bool
    178 s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial);
    179 
    180 #endif /* S_EXPRESSION_H */
    181