101e04c3fSmrg/* -*- c++ -*- */ 201e04c3fSmrg/* 301e04c3fSmrg * Copyright © 2010 Intel Corporation 401e04c3fSmrg * 501e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 601e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 701e04c3fSmrg * to deal in the Software without restriction, including without limitation 801e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 901e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 1001e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1101e04c3fSmrg * 1201e04c3fSmrg * The above copyright notice and this permission notice (including the next 1301e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1401e04c3fSmrg * Software. 1501e04c3fSmrg * 1601e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1701e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1801e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1901e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2001e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2101e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2201e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2301e04c3fSmrg */ 2401e04c3fSmrg 2501e04c3fSmrg#ifndef S_EXPRESSION_H 2601e04c3fSmrg#define S_EXPRESSION_H 2701e04c3fSmrg 2801e04c3fSmrg#include "util/strtod.h" 2901e04c3fSmrg#include "list.h" 3001e04c3fSmrg 3101e04c3fSmrg/* Type-safe downcasting macros (also safe to pass NULL) */ 3201e04c3fSmrg#define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \ 3301e04c3fSmrg : NULL 3401e04c3fSmrg#define SX_AS_LIST(x) SX_AS_(list, x) 3501e04c3fSmrg#define SX_AS_SYMBOL(x) SX_AS_(symbol, x) 3601e04c3fSmrg#define SX_AS_NUMBER(x) SX_AS_(number, x) 3701e04c3fSmrg#define SX_AS_INT(x) SX_AS_(int, x) 3801e04c3fSmrg 3901e04c3fSmrg/* Pattern matching macros */ 4001e04c3fSmrg#define MATCH(list, pat) s_match(list, ARRAY_SIZE(pat), pat, false) 4101e04c3fSmrg#define PARTIAL_MATCH(list, pat) s_match(list, ARRAY_SIZE(pat), pat, true) 4201e04c3fSmrg 4301e04c3fSmrg/* For our purposes, S-Expressions are: 4401e04c3fSmrg * - <int> 4501e04c3fSmrg * - <float> 4601e04c3fSmrg * - symbol 4701e04c3fSmrg * - (expr1 expr2 ... exprN) where exprN is an S-Expression 4801e04c3fSmrg * 4901e04c3fSmrg * Unlike LISP/Scheme, we do not support (foo . bar) pairs. 5001e04c3fSmrg */ 5101e04c3fSmrgclass s_expression : public exec_node 5201e04c3fSmrg{ 5301e04c3fSmrgpublic: 5401e04c3fSmrg /** 5501e04c3fSmrg * Read an S-Expression from the given string. 5601e04c3fSmrg * Advances the supplied pointer to just after the expression read. 5701e04c3fSmrg * 5801e04c3fSmrg * Any allocation will be performed with 'ctx' as the ralloc owner. 5901e04c3fSmrg */ 6001e04c3fSmrg static s_expression *read_expression(void *ctx, const char *&src); 6101e04c3fSmrg 6201e04c3fSmrg /** 6301e04c3fSmrg * Print out an S-Expression. Useful for debugging. 6401e04c3fSmrg */ 6501e04c3fSmrg virtual void print() = 0; 6601e04c3fSmrg 6701e04c3fSmrg virtual bool is_list() const { return false; } 6801e04c3fSmrg virtual bool is_symbol() const { return false; } 6901e04c3fSmrg virtual bool is_number() const { return false; } 7001e04c3fSmrg virtual bool is_int() const { return false; } 7101e04c3fSmrg 7201e04c3fSmrgprotected: 7301e04c3fSmrg s_expression() { } 7401e04c3fSmrg}; 7501e04c3fSmrg 7601e04c3fSmrg/* Atoms */ 7701e04c3fSmrg 7801e04c3fSmrgclass s_number : public s_expression 7901e04c3fSmrg{ 8001e04c3fSmrgpublic: 8101e04c3fSmrg bool is_number() const { return true; } 8201e04c3fSmrg 8301e04c3fSmrg virtual float fvalue() = 0; 8401e04c3fSmrg 8501e04c3fSmrgprotected: 8601e04c3fSmrg s_number() { } 8701e04c3fSmrg}; 8801e04c3fSmrg 8901e04c3fSmrgclass s_int : public s_number 9001e04c3fSmrg{ 9101e04c3fSmrgpublic: 9201e04c3fSmrg s_int(int x) : val(x) { } 9301e04c3fSmrg 9401e04c3fSmrg bool is_int() const { return true; } 9501e04c3fSmrg 9601e04c3fSmrg float fvalue() { return float(this->val); } 9701e04c3fSmrg int value() { return this->val; } 9801e04c3fSmrg 9901e04c3fSmrg void print(); 10001e04c3fSmrg 10101e04c3fSmrgprivate: 10201e04c3fSmrg int val; 10301e04c3fSmrg}; 10401e04c3fSmrg 10501e04c3fSmrgclass s_float : public s_number 10601e04c3fSmrg{ 10701e04c3fSmrgpublic: 10801e04c3fSmrg s_float(float x) : val(x) { } 10901e04c3fSmrg 11001e04c3fSmrg float fvalue() { return this->val; } 11101e04c3fSmrg 11201e04c3fSmrg void print(); 11301e04c3fSmrg 11401e04c3fSmrgprivate: 11501e04c3fSmrg float val; 11601e04c3fSmrg}; 11701e04c3fSmrg 11801e04c3fSmrgclass s_symbol : public s_expression 11901e04c3fSmrg{ 12001e04c3fSmrgpublic: 12101e04c3fSmrg s_symbol(const char *, size_t); 12201e04c3fSmrg 12301e04c3fSmrg bool is_symbol() const { return true; } 12401e04c3fSmrg 12501e04c3fSmrg const char *value() { return this->str; } 12601e04c3fSmrg 12701e04c3fSmrg void print(); 12801e04c3fSmrg 12901e04c3fSmrgprivate: 13001e04c3fSmrg const char *str; 13101e04c3fSmrg}; 13201e04c3fSmrg 13301e04c3fSmrg/* Lists of expressions: (expr1 ... exprN) */ 13401e04c3fSmrgclass s_list : public s_expression 13501e04c3fSmrg{ 13601e04c3fSmrgpublic: 13701e04c3fSmrg s_list(); 13801e04c3fSmrg 13901e04c3fSmrg virtual bool is_list() const { return true; } 14001e04c3fSmrg 14101e04c3fSmrg void print(); 14201e04c3fSmrg 14301e04c3fSmrg exec_list subexpressions; 14401e04c3fSmrg}; 14501e04c3fSmrg 14601e04c3fSmrg// ------------------------------------------------------------ 14701e04c3fSmrg 14801e04c3fSmrg/** 14901e04c3fSmrg * Part of a pattern to match - essentially a record holding a pointer to the 15001e04c3fSmrg * storage for the component to match, along with the appropriate type. 15101e04c3fSmrg */ 15201e04c3fSmrgclass s_pattern { 15301e04c3fSmrgpublic: 15401e04c3fSmrg s_pattern(s_expression *&s) : p_expr(&s), type(EXPR) { } 15501e04c3fSmrg s_pattern(s_list *&s) : p_list(&s), type(LIST) { } 15601e04c3fSmrg s_pattern(s_symbol *&s) : p_symbol(&s), type(SYMBOL) { } 15701e04c3fSmrg s_pattern(s_number *&s) : p_number(&s), type(NUMBER) { } 15801e04c3fSmrg s_pattern(s_int *&s) : p_int(&s), type(INT) { } 15901e04c3fSmrg s_pattern(const char *str) : literal(str), type(STRING) { } 16001e04c3fSmrg 16101e04c3fSmrg bool match(s_expression *expr); 16201e04c3fSmrg 16301e04c3fSmrgprivate: 16401e04c3fSmrg union { 16501e04c3fSmrg s_expression **p_expr; 16601e04c3fSmrg s_list **p_list; 16701e04c3fSmrg s_symbol **p_symbol; 16801e04c3fSmrg s_number **p_number; 16901e04c3fSmrg s_int **p_int; 17001e04c3fSmrg const char *literal; 17101e04c3fSmrg }; 17201e04c3fSmrg enum { EXPR, LIST, SYMBOL, NUMBER, INT, STRING } type; 17301e04c3fSmrg}; 17401e04c3fSmrg 17501e04c3fSmrgbool 17601e04c3fSmrgs_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial); 17701e04c3fSmrg 17801e04c3fSmrg#endif /* S_EXPRESSION_H */ 179