Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 "main/core.h" /* for Elements */
  30. #include "strtod.h"
  31. #include "list.h"
  32.  
  33. /* Type-safe downcasting macros (also safe to pass NULL) */
  34. #define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \
  35.                                                            : NULL
  36. #define SX_AS_LIST(x)   SX_AS_(list, x)
  37. #define SX_AS_SYMBOL(x) SX_AS_(symbol, x)
  38. #define SX_AS_NUMBER(x) SX_AS_(number, x)
  39. #define SX_AS_INT(x)    SX_AS_(int, x)
  40.  
  41. /* Pattern matching macros */
  42. #define MATCH(list, pat) s_match(list, Elements(pat), pat, false)
  43. #define PARTIAL_MATCH(list, pat) s_match(list, Elements(pat), pat, true)
  44.  
  45. /* For our purposes, S-Expressions are:
  46.  * - <int>
  47.  * - <float>
  48.  * - symbol
  49.  * - (expr1 expr2 ... exprN)     where exprN is an S-Expression
  50.  *
  51.  * Unlike LISP/Scheme, we do not support (foo . bar) pairs.
  52.  */
  53. class s_expression : public exec_node
  54. {
  55. public:
  56.    /**
  57.     * Read an S-Expression from the given string.
  58.     * Advances the supplied pointer to just after the expression read.
  59.     *
  60.     * Any allocation will be performed with 'ctx' as the ralloc owner.
  61.     */
  62.    static s_expression *read_expression(void *ctx, const char *&src);
  63.  
  64.    /**
  65.     * Print out an S-Expression.  Useful for debugging.
  66.     */
  67.    virtual void print() = 0;
  68.  
  69.    virtual bool is_list()   const { return false; }
  70.    virtual bool is_symbol() const { return false; }
  71.    virtual bool is_number() const { return false; }
  72.    virtual bool is_int()    const { return false; }
  73.  
  74. protected:
  75.    s_expression() { }
  76. };
  77.  
  78. /* Atoms */
  79.  
  80. class s_number : public s_expression
  81. {
  82. public:
  83.    bool is_number() const { return true; }
  84.  
  85.    virtual float fvalue() = 0;
  86.  
  87. protected:
  88.    s_number() { }
  89. };
  90.  
  91. class s_int : public s_number
  92. {
  93. public:
  94.    s_int(int x) : val(x) { }
  95.  
  96.    bool is_int() const { return true; }
  97.  
  98.    float fvalue() { return float(this->val); }
  99.    int value() { return this->val; }
  100.  
  101.    void print();
  102.  
  103. private:
  104.    int val;
  105. };
  106.  
  107. class s_float : public s_number
  108. {
  109. public:
  110.    s_float(float x) : val(x) { }
  111.  
  112.    float fvalue() { return this->val; }
  113.  
  114.    void print();
  115.  
  116. private:
  117.    float val;
  118. };
  119.  
  120. class s_symbol : public s_expression
  121. {
  122. public:
  123.    s_symbol(const char *, size_t);
  124.  
  125.    bool is_symbol() const { return true; }
  126.  
  127.    const char *value() { return this->str; }
  128.  
  129.    void print();
  130.  
  131. private:
  132.    const char *str;
  133. };
  134.  
  135. /* Lists of expressions: (expr1 ... exprN) */
  136. class s_list : public s_expression
  137. {
  138. public:
  139.    s_list();
  140.  
  141.    virtual bool is_list() const { return true; }
  142.  
  143.    void print();
  144.  
  145.    exec_list subexpressions;
  146. };
  147.  
  148. // ------------------------------------------------------------
  149.  
  150. /**
  151.  * Part of a pattern to match - essentially a record holding a pointer to the
  152.  * storage for the component to match, along with the appropriate type.
  153.  */
  154. class s_pattern {
  155. public:
  156.    s_pattern(s_expression *&s) : p_expr(&s),   type(EXPR)   { }
  157.    s_pattern(s_list       *&s) : p_list(&s),   type(LIST)   { }
  158.    s_pattern(s_symbol     *&s) : p_symbol(&s), type(SYMBOL) { }
  159.    s_pattern(s_number     *&s) : p_number(&s), type(NUMBER) { }
  160.    s_pattern(s_int        *&s) : p_int(&s),    type(INT)    { }
  161.    s_pattern(const char *str)  : literal(str), type(STRING) { }
  162.  
  163.    bool match(s_expression *expr);
  164.  
  165. private:
  166.    union {
  167.       s_expression **p_expr;
  168.       s_list       **p_list;
  169.       s_symbol     **p_symbol;
  170.       s_number     **p_number;
  171.       s_int        **p_int;
  172.       const char *literal;
  173.    };
  174.    enum { EXPR, LIST, SYMBOL, NUMBER, INT, STRING } type;
  175. };
  176.  
  177. bool
  178. s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial);
  179.  
  180. #endif /* S_EXPRESSION_H */
  181.