Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | 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. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <assert.h>
  29. #include "s_expression.h"
  30.  
  31. s_symbol::s_symbol(const char *tmp, size_t n)
  32. {
  33.    this->str = ralloc_strndup (this, tmp, n);
  34.    assert(this->str != NULL);
  35. }
  36.  
  37. s_list::s_list()
  38. {
  39. }
  40.  
  41. unsigned
  42. s_list::length() const
  43. {
  44.    unsigned i = 0;
  45.    foreach_iter(exec_list_iterator, it, this->subexpressions) {
  46.       i++;
  47.    }
  48.    return i;
  49. }
  50.  
  51. static s_expression *
  52. read_atom(void *ctx, const char *& src)
  53. {
  54.    s_expression *expr = NULL;
  55.  
  56.    // Skip leading spaces.
  57.    src += strspn(src, " \v\t\r\n");
  58.  
  59.    size_t n = strcspn(src, "( \v\t\r\n)");
  60.    if (n == 0)
  61.       return NULL; // no atom
  62.  
  63.    // Check if the atom is a number.
  64.    char *float_end = NULL;
  65.    double f = glsl_strtod(src, &float_end);
  66.    if (float_end != src) {
  67.       char *int_end = NULL;
  68.       int i = strtol(src, &int_end, 10);
  69.       // If strtod matched more characters, it must have a decimal part
  70.       if (float_end > int_end)
  71.          expr = new(ctx) s_float(f);
  72.       else
  73.          expr = new(ctx) s_int(i);
  74.    } else {
  75.       // Not a number; return a symbol.
  76.       expr = new(ctx) s_symbol(src, n);
  77.    }
  78.  
  79.    src += n;
  80.  
  81.    return expr;
  82. }
  83.  
  84. s_expression *
  85. s_expression::read_expression(void *ctx, const char *&src)
  86. {
  87.    assert(src != NULL);
  88.  
  89.    s_expression *atom = read_atom(ctx, src);
  90.    if (atom != NULL)
  91.       return atom;
  92.  
  93.    // Skip leading spaces.
  94.    src += strspn(src, " \v\t\r\n");
  95.    if (src[0] == '(') {
  96.       ++src;
  97.  
  98.       s_list *list = new(ctx) s_list;
  99.       s_expression *expr;
  100.  
  101.       while ((expr = read_expression(ctx, src)) != NULL) {
  102.          list->subexpressions.push_tail(expr);
  103.       }
  104.       src += strspn(src, " \v\t\r\n");
  105.       if (src[0] != ')') {
  106.          printf("Unclosed expression (check your parenthesis).\n");
  107.          return NULL;
  108.       }
  109.       ++src;
  110.       return list;
  111.    }
  112.    return NULL;
  113. }
  114.  
  115. void s_int::print()
  116. {
  117.    printf("%d", this->val);
  118. }
  119.  
  120. void s_float::print()
  121. {
  122.    printf("%f", this->val);
  123. }
  124.  
  125. void s_symbol::print()
  126. {
  127.    printf("%s", this->str);
  128. }
  129.  
  130. void s_list::print()
  131. {
  132.    printf("(");
  133.    foreach_iter(exec_list_iterator, it, this->subexpressions) {
  134.       s_expression *expr = (s_expression*) it.get();
  135.       expr->print();
  136.       if (!expr->next->is_tail_sentinel())
  137.          printf(" ");
  138.    }
  139.    printf(")");
  140. }
  141.  
  142.