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 "strtod.h"
30#include "list.h"
31
32#define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \
33                                                           : NULL
34#define SX_AS_LIST(x)   SX_AS_(list, x)
35#define SX_AS_SYMBOL(x) SX_AS_(symbol, x)
36#define SX_AS_NUMBER(x) SX_AS_(number, x)
37#define SX_AS_INT(x)    SX_AS_(int, x)
38
39/* For our purposes, S-Expressions are:
40 * - <int>
41 * - <float>
42 * - symbol
43 * - (expr1 expr2 ... exprN)     where exprN is an S-Expression
44 *
45 * Unlike LISP/Scheme, we do not support (foo . bar) pairs.
46 */
47class s_expression : public exec_node
48{
49public:
50   /**
51    * Read an S-Expression from the given string.
52    * Advances the supplied pointer to just after the expression read.
53    *
54    * Any allocation will be performed with 'ctx' as the hieralloc owner.
55    */
56   static s_expression *read_expression(void *ctx, const char *&src);
57
58   /**
59    * Print out an S-Expression.  Useful for debugging.
60    */
61   virtual void print() = 0;
62
63   virtual bool is_list()   const { return false; }
64   virtual bool is_symbol() const { return false; }
65   virtual bool is_number() const { return false; }
66   virtual bool is_int()    const { return false; }
67
68protected:
69   s_expression() { }
70   virtual ~s_expression() { } // GCC error about accessible nonvirtual dctor
71};
72
73/* Atoms */
74
75class s_number : public s_expression
76{
77public:
78   bool is_number() const { return true; }
79
80   virtual float fvalue() = 0;
81
82protected:
83   s_number() { }
84};
85
86class s_int : public s_number
87{
88public:
89   s_int(int x) : val(x) { }
90
91   bool is_int() const { return true; }
92
93   float fvalue() { return float(this->val); }
94   int value() { return this->val; }
95
96   void print();
97
98private:
99   int val;
100};
101
102class s_float : public s_number
103{
104public:
105   s_float(float x) : val(x) { }
106
107   float fvalue() { return this->val; }
108
109   void print();
110
111private:
112   float val;
113};
114
115class s_symbol : public s_expression
116{
117public:
118   s_symbol(const char *, size_t);
119
120   bool is_symbol() const { return true; }
121
122   const char *value() { return this->str; }
123
124   void print();
125
126private:
127   char *str;
128};
129
130/* Lists of expressions: (expr1 ... exprN) */
131class s_list : public s_expression
132{
133public:
134   s_list();
135
136   virtual bool is_list() const { return true; }
137   unsigned length() const;
138
139   void print();
140
141   exec_list subexpressions;
142};
143
144#endif /* S_EXPRESSION_H */
145