11bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke/* -*- c++ -*- */ 21bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke/* 31bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Copyright © 2010 Intel Corporation 41bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * 51bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Permission is hereby granted, free of charge, to any person obtaining a 61bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * copy of this software and associated documentation files (the "Software"), 71bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * to deal in the Software without restriction, including without limitation 81bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * the rights to use, copy, modify, merge, publish, distribute, sublicense, 91bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * and/or sell copies of the Software, and to permit persons to whom the 101bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Software is furnished to do so, subject to the following conditions: 111bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * 121bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * The above copyright notice and this permission notice (including the next 131bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * paragraph) shall be included in all copies or substantial portions of the 141bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Software. 151bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * 161bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 171bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 181bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 191bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 201bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 211bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 221bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * DEALINGS IN THE SOFTWARE. 231bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke */ 241bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 251bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#pragma once 261bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#ifndef S_EXPRESSION_H 271bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#define S_EXPRESSION_H 281bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 29daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke#include "main/core.h" /* for Elements */ 30bb10e081c8ddc452bca44ba583f239219a5b9372Brian Paul#include "strtod.h" 311bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#include "list.h" 321bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 33daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke/* Type-safe downcasting macros (also safe to pass NULL) */ 341bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \ 351bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke : NULL 361bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#define SX_AS_LIST(x) SX_AS_(list, x) 371bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#define SX_AS_SYMBOL(x) SX_AS_(symbol, x) 381bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#define SX_AS_NUMBER(x) SX_AS_(number, x) 391bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#define SX_AS_INT(x) SX_AS_(int, x) 401bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 41daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke/* Pattern matching macros */ 42daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke#define MATCH(list, pat) s_match(list, Elements(pat), pat, false) 43daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke#define PARTIAL_MATCH(list, pat) s_match(list, Elements(pat), pat, true) 44daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke 451bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke/* For our purposes, S-Expressions are: 461bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * - <int> 471bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * - <float> 481bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * - symbol 491bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * - (expr1 expr2 ... exprN) where exprN is an S-Expression 501bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * 511bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Unlike LISP/Scheme, we do not support (foo . bar) pairs. 521bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke */ 531bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeclass s_expression : public exec_node 541bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke{ 551bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkepublic: 561bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke /** 571bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Read an S-Expression from the given string. 581bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Advances the supplied pointer to just after the expression read. 591660a2954797e056caba319c5d6c70b0d4be22feCarl Worth * 60d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke * Any allocation will be performed with 'ctx' as the ralloc owner. 611bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke */ 621660a2954797e056caba319c5d6c70b0d4be22feCarl Worth static s_expression *read_expression(void *ctx, const char *&src); 631bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 641bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke /** 651bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke * Print out an S-Expression. Useful for debugging. 661bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke */ 671bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke virtual void print() = 0; 681bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 691bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke virtual bool is_list() const { return false; } 701bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke virtual bool is_symbol() const { return false; } 711bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke virtual bool is_number() const { return false; } 721bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke virtual bool is_int() const { return false; } 731bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 741bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeprotected: 751bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke s_expression() { } 761bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke}; 771bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 781bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke/* Atoms */ 791bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 801bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeclass s_number : public s_expression 811bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke{ 821bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkepublic: 831bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke bool is_number() const { return true; } 841bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 851bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke virtual float fvalue() = 0; 861bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 871bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeprotected: 881bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke s_number() { } 891bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke}; 901bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 911bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeclass s_int : public s_number 921bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke{ 931bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkepublic: 941bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke s_int(int x) : val(x) { } 951bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 961bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke bool is_int() const { return true; } 971bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 981bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke float fvalue() { return float(this->val); } 991bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke int value() { return this->val; } 1001bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1011bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke void print(); 1021bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1031bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeprivate: 1041bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke int val; 1051bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke}; 1061bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1071bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeclass s_float : public s_number 1081bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke{ 1091bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkepublic: 1101bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke s_float(float x) : val(x) { } 1111bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1121bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke float fvalue() { return this->val; } 1131bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1141bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke void print(); 1151bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1161bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeprivate: 1171bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke float val; 1181bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke}; 1191bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1201bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeclass s_symbol : public s_expression 1211bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke{ 1221bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkepublic: 123365ce61997a28a0c0dad79e7d3f7616e57f105f5Kenneth Graunke s_symbol(const char *, size_t); 1241bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1251bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke bool is_symbol() const { return true; } 1261bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1271bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke const char *value() { return this->str; } 1281bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1291bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke void print(); 1301bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1311bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeprivate: 1323875526926123259521514de9c8d675e3797275aKenneth Graunke const char *str; 1331bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke}; 1341bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1351bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke/* Lists of expressions: (expr1 ... exprN) */ 1361bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkeclass s_list : public s_expression 1371bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke{ 1381bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunkepublic: 1391bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke s_list(); 1401bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1411bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke virtual bool is_list() const { return true; } 1421bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1431bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke void print(); 1441bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 1451bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke exec_list subexpressions; 1461bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke}; 1471bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke 148daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke// ------------------------------------------------------------ 149daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke 150daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke/** 151daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke * Part of a pattern to match - essentially a record holding a pointer to the 152daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke * storage for the component to match, along with the appropriate type. 153daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke */ 154daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunkeclass s_pattern { 155daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunkepublic: 156daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_pattern(s_expression *&s) : p_expr(&s), type(EXPR) { } 157daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_pattern(s_list *&s) : p_list(&s), type(LIST) { } 158daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_pattern(s_symbol *&s) : p_symbol(&s), type(SYMBOL) { } 159daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_pattern(s_number *&s) : p_number(&s), type(NUMBER) { } 160daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_pattern(s_int *&s) : p_int(&s), type(INT) { } 161daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_pattern(const char *str) : literal(str), type(STRING) { } 162daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke 163daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke bool match(s_expression *expr); 164daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke 165daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunkeprivate: 166daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke union { 167daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_expression **p_expr; 168daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_list **p_list; 169daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_symbol **p_symbol; 170daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_number **p_number; 171daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke s_int **p_int; 172daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke const char *literal; 173daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke }; 174daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke enum { EXPR, LIST, SYMBOL, NUMBER, INT, STRING } type; 175daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke}; 176daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke 177daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunkebool 178daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunkes_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial); 179daeb0c646e0d652bfa16d326028753ecf092c0c9Kenneth Graunke 1801bfe1c3fdde39235ccbd8fc3da84a1603e919bc3Kenneth Graunke#endif /* S_EXPRESSION_H */ 181