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