From 29285882676388aacff123e8bdf025904abf8ea9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 Jun 2010 15:32:15 -0700 Subject: glsl2: Move the compiler to the subdirectory it will live in in Mesa. --- src/glsl/s_expression.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/glsl/s_expression.cpp (limited to 'src/glsl/s_expression.cpp') diff --git a/src/glsl/s_expression.cpp b/src/glsl/s_expression.cpp new file mode 100644 index 0000000000..26be23ea8f --- /dev/null +++ b/src/glsl/s_expression.cpp @@ -0,0 +1,131 @@ +/* -*- c++ -*- */ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "s_expression.h" + +s_symbol::s_symbol(const char *tmp) +{ + this->str = talloc_strdup (this, tmp); + assert(this->str != NULL); +} + +s_list::s_list() +{ +} + +unsigned +s_list::length() const +{ + unsigned i = 0; + foreach_iter(exec_list_iterator, it, this->subexpressions) { + i++; + } + return i; +} + +static s_expression * +read_atom(void *ctx, const char *& src) +{ + char buf[101]; + int n; + if (sscanf(src, " %100[^( \v\t\r\n)]%n", buf, &n) != 1) + return NULL; // no atom + src += n; + + // Check if the atom is a number. + char *float_end = NULL; + double f = strtod(buf, &float_end); + if (float_end != buf) { + char *int_end = NULL; + int i = strtol(buf, &int_end, 10); + // If strtod matched more characters, it must have a decimal part + if (float_end > int_end) + return new(ctx) s_float(f); + + return new(ctx) s_int(i); + } + // Not a number; return a symbol. + return new(ctx) s_symbol(buf); +} + +s_expression * +s_expression::read_expression(void *ctx, const char *&src) +{ + assert(src != NULL); + + s_expression *atom = read_atom(ctx, src); + if (atom != NULL) + return atom; + + char c; + int n; + if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') { + src += n; + + s_list *list = new(ctx) s_list; + s_expression *expr; + + while ((expr = read_expression(ctx, src)) != NULL) { + list->subexpressions.push_tail(expr); + } + if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') { + printf("Unclosed expression (check your parenthesis).\n"); + return NULL; + } + src += n; + return list; + } + return NULL; +} + +void s_int::print() +{ + printf("%d", this->val); +} + +void s_float::print() +{ + printf("%f", this->val); +} + +void s_symbol::print() +{ + printf("%s", this->str); +} + +void s_list::print() +{ + printf("("); + foreach_iter(exec_list_iterator, it, this->subexpressions) { + s_expression *expr = (s_expression*) it.get(); + expr->print(); + printf(" "); + } + printf(")"); +} + -- cgit v1.2.3 From 365ce61997a28a0c0dad79e7d3f7616e57f105f5 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 18 Aug 2010 18:03:22 -0700 Subject: glsl: Replace sscanf in s_expression reader with strspn and strcspn. This seems to give roughly a 20% speedup. --- src/glsl/s_expression.cpp | 49 ++++++++++++++++++++++++++++------------------- src/glsl/s_expression.h | 2 +- 2 files changed, 30 insertions(+), 21 deletions(-) (limited to 'src/glsl/s_expression.cpp') diff --git a/src/glsl/s_expression.cpp b/src/glsl/s_expression.cpp index 26be23ea8f..4458c48d6b 100644 --- a/src/glsl/s_expression.cpp +++ b/src/glsl/s_expression.cpp @@ -28,9 +28,9 @@ #include #include "s_expression.h" -s_symbol::s_symbol(const char *tmp) +s_symbol::s_symbol(const char *tmp, size_t n) { - this->str = talloc_strdup (this, tmp); + this->str = talloc_strndup (this, tmp, n); assert(this->str != NULL); } @@ -51,26 +51,34 @@ s_list::length() const static s_expression * read_atom(void *ctx, const char *& src) { - char buf[101]; - int n; - if (sscanf(src, " %100[^( \v\t\r\n)]%n", buf, &n) != 1) + s_expression *expr = NULL; + + // Skip leading spaces. + src += strspn(src, " \v\t\r\n"); + + size_t n = strcspn(src, "( \v\t\r\n)"); + if (n == 0) return NULL; // no atom - src += n; // Check if the atom is a number. char *float_end = NULL; - double f = strtod(buf, &float_end); - if (float_end != buf) { + double f = strtod(src, &float_end); + if (float_end != src) { char *int_end = NULL; - int i = strtol(buf, &int_end, 10); + int i = strtol(src, &int_end, 10); // If strtod matched more characters, it must have a decimal part if (float_end > int_end) - return new(ctx) s_float(f); - - return new(ctx) s_int(i); + expr = new(ctx) s_float(f); + else + expr = new(ctx) s_int(i); + } else { + // Not a number; return a symbol. + expr = new(ctx) s_symbol(src, n); } - // Not a number; return a symbol. - return new(ctx) s_symbol(buf); + + src += n; + + return expr; } s_expression * @@ -82,10 +90,10 @@ s_expression::read_expression(void *ctx, const char *&src) if (atom != NULL) return atom; - char c; - int n; - if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') { - src += n; + // Skip leading spaces. + src += strspn(src, " \v\t\r\n"); + if (src[0] == '(') { + ++src; s_list *list = new(ctx) s_list; s_expression *expr; @@ -93,11 +101,12 @@ s_expression::read_expression(void *ctx, const char *&src) while ((expr = read_expression(ctx, src)) != NULL) { list->subexpressions.push_tail(expr); } - if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') { + src += strspn(src, " \v\t\r\n"); + if (src[0] != ')') { printf("Unclosed expression (check your parenthesis).\n"); return NULL; } - src += n; + ++src; return list; } return NULL; diff --git a/src/glsl/s_expression.h b/src/glsl/s_expression.h index 1a0c03c218..aa22475a1b 100644 --- a/src/glsl/s_expression.h +++ b/src/glsl/s_expression.h @@ -113,7 +113,7 @@ private: class s_symbol : public s_expression { public: - s_symbol(const char *); + s_symbol(const char *, size_t); bool is_symbol() const { return true; } -- cgit v1.2.3