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