Home | History | Annotate | Download | only in glsl
      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 <cstdio>
     26 #include <cstdlib>
     27 #include <cstring>
     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 = hieralloc_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