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