diff options
author | Tavian Barnes <tavianator@gmail.com> | 2011-05-15 16:10:51 -0600 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2011-05-15 16:10:51 -0600 |
commit | e5e88afdbf158e6df8f8c3328f308512819d9cf3 (patch) | |
tree | 2a011762c07c0087defcdc1f1022ffe32d532f49 | |
parent | a5a6b94c038e01ebf1e2de0a0774a69b02fb8e1e (diff) | |
download | dimension-e5e88afdbf158e6df8f8c3328f308512819d9cf3.tar.xz |
Rip out old client.
65 files changed, 2 insertions, 10555 deletions
@@ -21,17 +21,6 @@ Doxyfile # pkg-config files *.pc -# Files created by `make' -*.exe -/dimension/dimension -/dimension/directives.c -/dimension/directives.h -/dimension/directives.y -/dimension/grammar.c -/dimension/grammar.h -/dimension/grammar.y -/dimension/lexer.c - # Files created by `make check' /*/tests/*-test /*/tests/*.png @@ -39,7 +28,6 @@ Doxyfile # Files created by `make bench' /*/bench/bench-* -/*/bench/*.png # Files and folders created by libtool .libs/ @@ -1,16 +1,5 @@ Here's an overview of how the code is arranged: -Client (GPLv3): -=============== - -ENTRY POINT: dimension/main.c -Tokenizing: dimension/lexer.l -Language directives: dimension/tokenize.c -Parsing: dimension/common.rules -Extra parsing stuff: dimension/{common,grammar,directives}.* -Tests: dimension/tests/*.{pov,sh} -Benchmarks: dimension/bench/*.{sh,pov} - Library (LGPLv3): ================= diff --git a/Makefile.am b/Makefile.am index 898a0c0..0a2363d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,14 +18,12 @@ ########################################################################### ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = libdimension \ - dimension +SUBDIRS = libdimension EXTRA_DIST = autogen.sh bench: all-recursive cd libdimension && $(MAKE) $(AM_MAKEFLAGS) bench - cd dimension && $(MAKE) $(AM_MAKEFLAGS) bench doc: cd libdimension && $(MAKE) $(AM_MAKEFLAGS) doc diff --git a/configure.ac b/configure.ac index e8e8b8c..ea1345d 100644 --- a/configure.ac +++ b/configure.ac @@ -172,8 +172,5 @@ AC_CONFIG_FILES([Makefile libdimension/Doxyfile libdimension/bench/Makefile libdimension/libdimension.pc - libdimension/tests/Makefile - dimension/Makefile - dimension/bench/Makefile - dimension/tests/Makefile]) + libdimension/tests/Makefile]) AC_OUTPUT diff --git a/dimension/Makefile.am b/dimension/Makefile.am deleted file mode 100644 index 72aaad9..0000000 --- a/dimension/Makefile.am +++ /dev/null @@ -1,88 +0,0 @@ -########################################################################### -## Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> ## -## ## -## This file is part of The Dimension Build Suite. ## -## ## -## The Dimension Build Suite is free software; you can redistribute it ## -## and/or modify it under the terms of the GNU General Public License as ## -## published by the Free Software Foundation; either version 3 of the ## -## License, or (at your option) any later version. ## -## ## -## The Dimension Build Suite is distributed in the hope that it will be ## -## useful, but WITHOUT ANY WARRANTY; without even the implied warranty ## -## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## -## General Public License for more details. ## -## ## -## You should have received a copy of the GNU General Public License ## -## along with this program. If not, see <http://www.gnu.org/licenses/>. ## -########################################################################### - -SUBDIRS = bench \ - tests - -# Make dmnsn_error() backtraces useful -AM_LDFLAGS = -rdynamic - -INCLUDES = -I$(top_srcdir)/libdimension - -bin_PROGRAMS = dimension - -AM_YFLAGS = -d -BUILT_SOURCES = directives.h grammar.h -EXTRA_DIST = common.prologue \ - common.declarations \ - common.terminals \ - common.nonterminals \ - common.rules \ - directives.prologue \ - directives.declarations \ - directives.nonterminals \ - directives.rules \ - grammar.prologue \ - grammar.declarations \ - grammar.nonterminals \ - grammar.rules \ - grammar.epilogue - -grammar.y: grammar.prologue grammar.declarations grammar.nonterminals grammar.rules grammar.epilogue common.prologue common.declarations common.terminals common.nonterminals common.rules - @echo "%{" >$@ - @cat {common,grammar}.prologue >>$@ - @echo "%}" >>$@ - @cat common.terminals {grammar,common}.{declarations,nonterminals} >>$@ - @echo "%%" >>$@ - @cat grammar.rules common.rules >>$@ - @echo "%%" >>$@ - @cat grammar.epilogue >>$@ - -directives.y: directives.prologue directives.declarations directives.nonterminals directives.rules common.prologue common.declarations common.terminals common.nonterminals common.rules - @echo "%{" >$@ - @cat {common,directives}.prologue >>$@ - @echo "%}" >>$@ - @cat common.terminals {directives,common}.{declarations,nonterminals} >>$@ - @echo "%%" >>$@ - @cat directives.rules common.rules >>$@ - -dimension_SOURCES = directives.y \ - grammar.y \ - lexer.l \ - main.c \ - parse.c \ - parse.h \ - platform.c \ - platform.h \ - progressbar.c \ - progressbar.h \ - realize.c \ - realize.h \ - tokenize.c \ - tokenize.h \ - utility.c \ - utility.h \ - y.tab.h -dimension_LDADD = $(top_builddir)/libdimension/libdimension.la -dimension_LDFLAGS = $(AM_LDFLAGS) - -bench: all-recursive - cd bench && $(MAKE) $(AM_MAKEFLAGS) bench - -.PHONY: bench diff --git a/dimension/bench/Makefile.am b/dimension/bench/Makefile.am deleted file mode 100644 index e7fe03f..0000000 --- a/dimension/bench/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -########################################################################### -## Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> ## -## ## -## This file is part of The Dimension Build Suite. ## -## ## -## The Dimension Build Suite is free software; you can redistribute it ## -## and/or modify it under the terms of the GNU General Public License as ## -## published by the Free Software Foundation; either version 3 of the ## -## License, or (at your option) any later version. ## -## ## -## The Dimension Build Suite is distributed in the hope that it will be ## -## useful, but WITHOUT ANY WARRANTY; without even the implied warranty ## -## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## -## General Public License for more details. ## -## ## -## You should have received a copy of the GNU General Public License ## -## along with this program. If not, see <http://www.gnu.org/licenses/>. ## -########################################################################### - -ENVIRONMENT = top_builddir=$(top_builddir) - -bench: tokenize.sh parse.sh render.sh - $(ENVIRONMENT) ./tokenize.sh - $(ENVIRONMENT) ./parse.sh - $(ENVIRONMENT) ./render.sh - -.sh: - cp $(srcdir)/$@ . - -clean-local: - rm -f *.png - -EXTRA_DIST = bench.pov - -.PHONY: bench diff --git a/dimension/bench/bench.pov b/dimension/bench/bench.pov deleted file mode 100644 index a4f632f..0000000 --- a/dimension/bench/bench.pov +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Benchmark Suite. * - * * - * The Dimension Benchmark Suite is free software; you can redistribute * - * it and/or modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Benchmark Suite is distributed in the hope that it will * - * be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * - * the GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -camera { - location <3.0, 6.0, -11.0> - right x*image_width/image_height - look_at 0 -} - -background { - color rgb 1 -} - -// inside center sphere -light_source { - 0, - color rgb 1 -} - -light_source { - 2*y, - color rgb 1 -} - -/* plane { - y, - -1 - // *** hollow on - pigment { - rgb <0.73, 0.90, 0.97> - } - finish { - diffuse 0.35 - ambient .5 - } -} */ - -#macro sph(center) - sphere { - center, - 1 - texture { - // *** crackle - scale 0.5 - - /* *** texture_map { - [ 0.03 - pigment { - color rgb 1 - } - finish { - ambient 1 - } - normal { - facets size 0.1 - } - ] - [ 0.04 - pigment { - color rgbf <1, 1, 1, 0.9> - } - finish { - reflection { 0.2 } - specular 0.1 - roughness 0.02 - conserve_energy - } - normal { - facets size 0.1 - } - ] - } *** */ - } - interior { - ior 1.3 - } - } -#end - -union { - #declare Size = 4; - #declare I = -Size; - #while (I <= Size) - #declare J = -Size; - - #while (J <= Size) - #declare K = -Size; - - #while (K <= Size) - object { - sph(<2.5*I, 2.5*K, 2.5*J>) - } - - #declare K = K + 1; - #end - - #declare J = J + 1; - #end - - #declare I = I + 1; - #end -} diff --git a/dimension/bench/parse.sh b/dimension/bench/parse.sh deleted file mode 100755 index b7db055..0000000 --- a/dimension/bench/parse.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -######################################################################### -# Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Benchmark Suite. # -# # -# The Dimension Benchmark Suite is free software; you can redistribute # -# it and/or modify it under the terms of the GNU General Public License # -# as published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Benchmark Suite is distributed in the hope that it will # -# be useful, but WITHOUT ANY WARRANTY; without even the implied # -# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # -# the GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -for i in {1..10000}; do - echo ' -difference { - box { - <-1, -1, -1>, <1, 1, 1> - - rotate 45*x - - texture { - pigment { - color rgbft <0, 0, 1, 0.25, 0.5> - } - finish { - reflection { 0.5 } - } - } - - interior { - ior 1.1 - } - } - - sphere { - <0, 0, 0>, 1.25 - - texture { - pigment { - color rgb <0, 1, 0> - } - finish { - phong 0.2 - phong_size 40.0 - } - } - } -} -' -done | (time ${top_builddir}/dimension/dimension --parse /dev/stdin >/dev/null) diff --git a/dimension/bench/render.sh b/dimension/bench/render.sh deleted file mode 100755 index b661e53..0000000 --- a/dimension/bench/render.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Benchmark Suite. # -# # -# The Dimension Benchmark Suite is free software; you can redistribute # -# it and/or modify it under the terms of the GNU General Public License # -# as published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Benchmark Suite is distributed in the hope that it will # -# be useful, but WITHOUT ANY WARRANTY; without even the implied # -# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # -# the GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -echo -e "Single-threaded" -time ${top_builddir}/dimension/dimension -w1920 -h1080 --quality=1 --threads=1 bench.pov -echo -e "\nMulti-threaded" -time ${top_builddir}/dimension/dimension -w1920 -h1080 --quality=1 bench.pov diff --git a/dimension/bench/tokenize.sh b/dimension/bench/tokenize.sh deleted file mode 100755 index 1d833d5..0000000 --- a/dimension/bench/tokenize.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -######################################################################### -# Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Benchmark Suite. # -# # -# The Dimension Benchmark Suite is free software; you can redistribute # -# it and/or modify it under the terms of the GNU General Public License # -# as published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Benchmark Suite is distributed in the hope that it will # -# be useful, but WITHOUT ANY WARRANTY; without even the implied # -# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # -# the GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -for i in {1..10000}; do - echo '{}()[]+-*/,;?:&.|=<>!<= >= != "This is a string with escape sequences: \a\b\f\n\r\t\u2123\v\\\"" 1 123456789 01234567 0x123456789 -0x01 .1 0.1 1.0 0.123456789 -0.123456789 <1, 2.2, -3.03> Undefined' -done | (time ${top_builddir}/dimension/dimension --tokenize /dev/stdin >/dev/null) diff --git a/dimension/common.declarations b/dimension/common.declarations deleted file mode 100644 index 964798f..0000000 --- a/dimension/common.declarations +++ /dev/null @@ -1,33 +0,0 @@ -#line 2 "common.declarations" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -%define api.pure -%locations -%error-verbose - -%glr-parser - -%lex-param {const char *filename} -%lex-param {dmnsn_symbol_table *symtable} -%lex-param {void *yyscanner} - -%destructor { dmnsn_free($$); } <value> -%destructor { dmnsn_delete_astnode($$); } <astnode> diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals deleted file mode 100644 index a74d0d7..0000000 --- a/dimension/common.nonterminals +++ /dev/null @@ -1,117 +0,0 @@ -#line 2 "common.nonterminals" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -/* Fundamental language elements */ -%type <astnode> IDENTIFIER -%type <astnode> STRING - -/* Transformations */ -%type <astnode> TRANSFORMATION -%type <astnode> TRANSFORMATION_ITEMS -%type <astnode> TRANSFORMATION_ITEM - -/* The camera */ -%type <astnode> CAMERA -%type <astnode> CAMERA_ITEMS -%type <astnode> CAMERA_ITEM -%type <astnode> CAMERA_TYPE -%type <astnode> CAMERA_VECTOR -%type <astnode> CAMERA_MODIFIER - -/* Objects */ -%type <astnode> OBJECT -%type <astnode> FINITE_SOLID_OBJECT -%type <astnode> BOX -%type <astnode> CONE -%type <astnode> CYLINDER -%type <astnode> MAYBE_OPEN -%type <astnode> SPHERE -%type <astnode> TORUS -%type <astnode> TORUS_MODIFIERS -%type <astnode> INFINITE_SOLID_OBJECT -%type <astnode> PLANE -%type <astnode> CSG_OBJECT -%type <astnode> UNION -%type <astnode> INTERSECTION -%type <astnode> DIFFERENCE -%type <astnode> MERGE -%type <astnode> OBJECTS -%type <astnode> LIGHT_SOURCE - -/* Object modifiers */ -%type <astnode> OBJECT_MODIFIERS -%type <astnode> OBJECT_MODIFIER - -/* Patterns */ -%type <astnode> BLOCK_PATTERN_TYPE -%type <astnode> CONTINUOUS_PATTERN_TYPE -%type <astnode> PATTERN_TYPE - -/* Textures */ -%type <astnode> TEXTURE -%type <astnode> TEXTURE_ITEMS - -/* Pigments */ -%type <astnode> PIGMENT -%type <astnode> PIGMENT_BODY -%type <astnode> PIGMENT_TYPE -%type <astnode> PIGMENT_MODIFIERS -%type <astnode> COLOR_LIST2 -%type <astnode> COLOR_MAP -%type <astnode> COLOR_MAP_ENTRIES -%type <astnode> COLOR_MAP_ENTRY -%type <astnode> PIGMENT_LIST2 -%type <astnode> PIGMENT_MAP -%type <astnode> PIGMENT_MAP_ENTRIES -%type <astnode> PIGMENT_MAP_ENTRY -%type <astnode> BITMAP_TYPE - -/* Finishes */ -%type <astnode> FINISH -%type <astnode> FINISH_ITEMS -%type <astnode> REFLECTION -%type <astnode> REFLECTION_ITEMS - -/* Interiors */ -%type <astnode> INTERIOR -%type <astnode> INTERIOR_ITEMS - -/* Floats */ -%type <astnode> FLOAT -%type <astnode> INT -%type <astnode> FLOAT_LITERAL - -/* Vectors */ -%type <astnode> VECTOR -%type <astnode> VECTOR_LITERAL - -/* Generalized arithmetic expressions */ -%type <astnode> ARITH_EXPR -%type <astnode> CONDITIONAL -%type <astnode> MAX_LIST -%type <astnode> MIN_LIST - -/* Colors */ -%type <astnode> COLOR -%type <astnode> COLOR_BODY -%type <astnode> COLOR_VECTOR -%type <astnode> COLOR_KEYWORD_GROUP -%type <astnode> COLOR_KEYWORD_GROUP_INIT diff --git a/dimension/common.prologue b/dimension/common.prologue deleted file mode 100644 index 649f184..0000000 --- a/dimension/common.prologue +++ /dev/null @@ -1,154 +0,0 @@ -#line 2 "common.prologue" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "parse.h" -#include "tokenize.h" -#include "utility.h" -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> - -#define YYSTYPE dmnsn_parse_item -#define YYLTYPE dmnsn_parse_location - -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if (N) { \ - (Current).first_filename = YYRHSLOC(Rhs, 1).first_filename; \ - (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ - (Current).last_filename = YYRHSLOC(Rhs, N).last_filename; \ - (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ - (Current).parent = YYRHSLOC(Rhs, 1).parent; \ - } else { \ - (Current) = YYRHSLOC(Rhs, 0); \ - } \ - } while (0) - -/* Create a new astnode, populating filename, line, and col */ - -static dmnsn_astnode -dmnsn_new_astleaf(dmnsn_astnode_type type, YYLTYPE lloc) -{ - dmnsn_astnode astnode = { - .type = type, - .children = NULL, - .ptr = NULL, - .free_fn = NULL, - .refcount = dmnsn_malloc(sizeof(unsigned int)), - .location = lloc - }; - - *astnode.refcount = 1; - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode(dmnsn_astnode_type type, YYLTYPE lloc) -{ - dmnsn_astnode astnode = { - .type = type, - .children = dmnsn_new_array(sizeof(dmnsn_astnode)), - .ptr = NULL, - .free_fn = NULL, - .refcount = dmnsn_malloc(sizeof(unsigned int)), - .location = lloc - }; - - *astnode.refcount = 1; - return astnode; -} - -/* Semi-shallow copy */ -static void -dmnsn_copy_children(dmnsn_astnode dest, dmnsn_astnode src) -{ - for (size_t i = 0; i < dmnsn_array_size(src.children); ++i) { - dmnsn_astnode node; - dmnsn_array_get(src.children, i, &node); - ++*node.refcount; - - if (i < dmnsn_array_size(dest.children)) { - dmnsn_astnode clobbered; - dmnsn_array_get(dest.children, i, &clobbered); - dmnsn_delete_astnode(clobbered); - } - - dmnsn_array_set(dest.children, i, &node); - } -} - -static dmnsn_astnode -dmnsn_new_astnode1(dmnsn_astnode_type type, YYLTYPE lloc, dmnsn_astnode n1) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode2(dmnsn_astnode_type type, YYLTYPE lloc, - dmnsn_astnode n1, dmnsn_astnode n2) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - dmnsn_array_push(astnode.children, &n2); - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode3(dmnsn_astnode_type type, YYLTYPE lloc, - dmnsn_astnode n1, dmnsn_astnode n2, dmnsn_astnode n3) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - dmnsn_array_push(astnode.children, &n2); - dmnsn_array_push(astnode.children, &n3); - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode4(dmnsn_astnode_type type, YYLTYPE lloc, - dmnsn_astnode n1, dmnsn_astnode n2, dmnsn_astnode n3, - dmnsn_astnode n4) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - dmnsn_array_push(astnode.children, &n2); - dmnsn_array_push(astnode.children, &n3); - dmnsn_array_push(astnode.children, &n4); - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode5(dmnsn_astnode_type type, YYLTYPE lloc, - dmnsn_astnode n1, dmnsn_astnode n2, dmnsn_astnode n3, - dmnsn_astnode n4, dmnsn_astnode n5) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - dmnsn_array_push(astnode.children, &n2); - dmnsn_array_push(astnode.children, &n3); - dmnsn_array_push(astnode.children, &n4); - dmnsn_array_push(astnode.children, &n5); - return astnode; -} diff --git a/dimension/common.rules b/dimension/common.rules deleted file mode 100644 index a987c69..0000000 --- a/dimension/common.rules +++ /dev/null @@ -1,1177 +0,0 @@ -#line 2 "common.rules" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -/* Fundamental language elements */ - -IDENTIFIER: "identifier" { - $$ = dmnsn_new_astleaf(DMNSN_AST_IDENTIFIER, @$); - $$.ptr = dmnsn_strdup($1); - dmnsn_free($1); - } -; - -STRING: "string" { - $$ = dmnsn_new_astleaf(DMNSN_AST_STRING, @$); - $$.ptr = $1; - } -; - -/* Transformations */ - -TRANSFORMATION: "rotate" VECTOR { - dmnsn_astnode rotation - = dmnsn_new_astnode1(DMNSN_AST_ROTATION, @$, $2); - $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, rotation); - } - | "scale" VECTOR { - dmnsn_astnode scale - = dmnsn_new_astnode1(DMNSN_AST_SCALE, @$, $2); - $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, scale); - } - | "translate" VECTOR { - dmnsn_astnode translation - = dmnsn_new_astnode1(DMNSN_AST_TRANSLATION, @$, $2); - $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, - translation); - } - | "matrix" "<" FLOAT "," FLOAT "," FLOAT "," - FLOAT "," FLOAT "," FLOAT "," - FLOAT "," FLOAT "," FLOAT "," - FLOAT "," FLOAT "," FLOAT ">" - { - dmnsn_astnode matrix = dmnsn_new_astnode(DMNSN_AST_MATRIX, @$); - - dmnsn_array_push(matrix.children, &$3); - dmnsn_array_push(matrix.children, &$5); - dmnsn_array_push(matrix.children, &$7); - - dmnsn_array_push(matrix.children, &$9); - dmnsn_array_push(matrix.children, &$11); - dmnsn_array_push(matrix.children, &$13); - - dmnsn_array_push(matrix.children, &$15); - dmnsn_array_push(matrix.children, &$17); - dmnsn_array_push(matrix.children, &$19); - - dmnsn_array_push(matrix.children, &$21); - dmnsn_array_push(matrix.children, &$23); - dmnsn_array_push(matrix.children, &$25); - - $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, matrix); - } - | "transform" IDENTIFIER { - dmnsn_astnode *trans = dmnsn_find_symbol(symtable, $2.ptr); - if (!trans) { - dmnsn_diagnostic(@2, "unbound identifier '%s'", - (const char *)$2.ptr); - dmnsn_delete_astnode($2); - YYERROR; - } - if (trans->type != DMNSN_AST_TRANSFORMATION) { - dmnsn_diagnostic( - @2, "identifier '%s' is a %s; expected a %s", - (const char *)$2.ptr, - dmnsn_astnode_string(trans->type), - dmnsn_astnode_string(DMNSN_AST_TRANSFORMATION) - ); - dmnsn_delete_astnode($2); - YYERROR; - } - - $$ = dmnsn_new_astnode(DMNSN_AST_TRANSFORMATION, @$); - dmnsn_copy_children($$, *trans); - dmnsn_delete_astnode($2); - } - | "transform" "{" - TRANSFORMATION_ITEMS - "}" - { - $$ = $3; - } -; - -TRANSFORMATION_ITEMS: TRANSFORMATION_ITEM { - $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, $1); - } - | TRANSFORMATION_ITEMS TRANSFORMATION_ITEM { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -TRANSFORMATION_ITEM: IDENTIFIER { - dmnsn_astnode *trans = dmnsn_find_symbol(symtable, $1.ptr); - if (!trans) { - dmnsn_diagnostic(@1, "unbound identifier '%s'", - (const char *)$1.ptr); - dmnsn_delete_astnode($1); - YYERROR; - } - if (trans->type != DMNSN_AST_TRANSFORMATION) { - dmnsn_diagnostic( - @1, "identifier '%s' is a %s; expected a %s", - (const char *)$1.ptr, - dmnsn_astnode_string(trans->type), - dmnsn_astnode_string(DMNSN_AST_TRANSFORMATION) - ); - dmnsn_delete_astnode($1); - YYERROR; - } - - dmnsn_array_get(trans->children, 0, &$$); - ++*$$.refcount; - dmnsn_delete_astnode($1); - } - | TRANSFORMATION { - dmnsn_array_get($1.children, 0, &$$); - ++*$$.refcount; - dmnsn_delete_astnode($1); - } - | "inverse" { - $$ = dmnsn_new_astleaf(DMNSN_AST_INVERSE, @$); - } -; - -/* Cameras */ - -CAMERA: "camera" "{" - CAMERA_ITEMS - "}" - { - $$ = $3; - } -; - -CAMERA_ITEMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_CAMERA, @$); - } - | CAMERA_ITEMS CAMERA_ITEM { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -CAMERA_ITEM: CAMERA_TYPE - | CAMERA_VECTOR - | CAMERA_MODIFIER -; - -CAMERA_TYPE: "perspective" { - $$ = dmnsn_new_astleaf(DMNSN_AST_PERSPECTIVE, @$); - } -; - -CAMERA_VECTOR: "location" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_LOCATION, @$, $2); - } - | "right" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_RIGHT, @$, $2); - } - | "up" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_UP, @$, $2); - } - | "sky" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_SKY, @$, $2); - } - | "direction" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_DIRECTION, @$, $2); - } -; - -CAMERA_MODIFIER: "angle" FLOAT { - $$ = dmnsn_new_astnode1(DMNSN_AST_ANGLE, @$, $2); - } - | "look_at" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_LOOK_AT, @$, $2); - } - | TRANSFORMATION -; - -/* Objects */ - -OBJECT: FINITE_SOLID_OBJECT - | INFINITE_SOLID_OBJECT - | CSG_OBJECT - | LIGHT_SOURCE - | "object" "{" - IDENTIFIER - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode *object = dmnsn_find_symbol(symtable, $3.ptr); - if (!object) { - dmnsn_diagnostic(@3, "unbound identifier '%s'", (const char *)$3.ptr); - dmnsn_delete_astnode($3); - dmnsn_delete_astnode($4); - YYERROR; - } - - if (object->type == DMNSN_AST_OBJECT) { - dmnsn_delete_astnode($3); - - $$ = dmnsn_new_astnode(object->type, @$); - dmnsn_copy_children($$, *object); - - dmnsn_astnode *modifiers, orig_modifiers; - modifiers = dmnsn_array_at($$.children, 1); - dmnsn_array_get(object->children, - dmnsn_array_size(object->children) - 1, - &orig_modifiers); - dmnsn_delete_astnode(*modifiers); - *modifiers = dmnsn_new_astnode(DMNSN_AST_OBJECT_MODIFIERS, @4); - dmnsn_copy_children(*modifiers, orig_modifiers); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, $4.children) { - ++*astnode->refcount; - dmnsn_array_push(modifiers->children, astnode); - } - dmnsn_delete_astnode($4); - } else { - dmnsn_diagnostic(@3, - "identifier '%s' is a %s; expected an %s", - (const char *)$3.ptr, - dmnsn_astnode_string(object->type), - dmnsn_astnode_string(DMNSN_AST_OBJECT)); - dmnsn_delete_astnode($3); - dmnsn_delete_astnode($4); - YYERROR; - } - } - | "object" "{" - OBJECT - OBJECT_MODIFIERS - "}" - { - $$ = $3; - - dmnsn_astnode modifiers; - dmnsn_array_get($$.children, - dmnsn_array_size($$.children) - 1, - &modifiers); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, $4.children) { - ++*astnode->refcount; - dmnsn_array_push(modifiers.children, astnode); - } - - dmnsn_delete_astnode($4); - } -; - -FINITE_SOLID_OBJECT: BOX - | CONE - | CYLINDER - | SPHERE - | TORUS -; - -BOX: "box" "{" - VECTOR "," VECTOR - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode object = dmnsn_new_astnode2(DMNSN_AST_BOX, @$, $3, $5); - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $6); - } -; - -CONE: "cone" "{" - VECTOR "," FLOAT "," VECTOR "," FLOAT - MAYBE_OPEN - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode object - = dmnsn_new_astnode5(DMNSN_AST_CONE, @$, $3, $5, $7, $9, $10); - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $11); - } -; - -CYLINDER: "cylinder" "{" - VECTOR "," VECTOR "," FLOAT - MAYBE_OPEN - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode object - = dmnsn_new_astnode4(DMNSN_AST_CYLINDER, @$, $3, $5, $7, $8); - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $9); - } -; - -MAYBE_OPEN: /* empty */ { - $$ = dmnsn_new_ast_integer(false); - } - | "open" { - $$ = dmnsn_new_ast_integer(true); - } -; - -SPHERE: "sphere" "{" - VECTOR "," FLOAT - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode object = dmnsn_new_astnode2(DMNSN_AST_SPHERE, @$, $3, $5); - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $6); - } -; - -TORUS: "torus" "{" - FLOAT "," FLOAT - TORUS_MODIFIERS - "}" - { - dmnsn_astnode object = dmnsn_new_astnode2(DMNSN_AST_TORUS, @$, $3, $5); - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $6); - } -; - -TORUS_MODIFIERS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_OBJECT_MODIFIERS, @$); - } - | TORUS_MODIFIERS OBJECT_MODIFIER { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } - | TORUS_MODIFIERS "sturm" { - dmnsn_diagnostic(@2, - "WARNING: Dimension does not use 'sturm';" - " ignored."); - dmnsn_astnode on = dmnsn_new_ast_integer(true); - dmnsn_astnode sturm = dmnsn_new_astnode1(DMNSN_AST_STURM, @2, - on); - $$ = $1; - dmnsn_array_push($$.children, &sturm); - } - | TORUS_MODIFIERS "sturm" INT { - dmnsn_diagnostic(@2, - "WARNING: Dimension does not use 'sturm';" - " ignored."); - dmnsn_astnode sturm = dmnsn_new_astnode1(DMNSN_AST_STURM, @2, - $3); - $$ = $1; - dmnsn_array_push($$.children, &sturm); - } -; - -INFINITE_SOLID_OBJECT: PLANE -; - -PLANE: "plane" "{" - VECTOR "," FLOAT - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode object = dmnsn_new_astnode2(DMNSN_AST_PLANE, @$, $3, $5); - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $6); - } -; - -CSG_OBJECT: UNION - | INTERSECTION - | DIFFERENCE - | MERGE -; - -UNION: "union" "{" - OBJECTS - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode csg_union = $3; - csg_union.type = DMNSN_AST_UNION; - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, csg_union, $4); - } -; - -INTERSECTION: "intersection" "{" - OBJECTS - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode intersection = $3; - intersection.type = DMNSN_AST_INTERSECTION; - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, intersection, $4); - } -; - -DIFFERENCE: "difference" "{" - OBJECTS - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode difference = $3; - difference.type = DMNSN_AST_DIFFERENCE; - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, difference, $4); - } -; - -MERGE: "merge" "{" - OBJECTS - OBJECT_MODIFIERS - "}" - { - dmnsn_astnode merge = $3; - merge.type = DMNSN_AST_MERGE; - $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, merge, $4); - } -; - -OBJECTS: OBJECT { - $$ = dmnsn_new_astnode1(DMNSN_AST_ARRAY, @$, $1); - } - | OBJECTS OBJECT { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -LIGHT_SOURCE: "light_source" "{" - VECTOR "," COLOR - OBJECT_MODIFIERS - "}" - { - $$ = dmnsn_new_astnode3(DMNSN_AST_LIGHT_SOURCE, @$, $3, $5, $6); - } -; - -/* Object modifiers */ - -OBJECT_MODIFIERS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_OBJECT_MODIFIERS, @$); - } - | OBJECT_MODIFIERS OBJECT_MODIFIER { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -OBJECT_MODIFIER: TRANSFORMATION - | TEXTURE - | PIGMENT - | FINISH - | INTERIOR -; - -/* Patterns */ - -BLOCK_PATTERN_TYPE: "checker" { - dmnsn_astnode p = dmnsn_new_astleaf(DMNSN_AST_CHECKER, @$); - $$ = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @$, p); - } -; - -CONTINUOUS_PATTERN_TYPE: "gradient" VECTOR { - dmnsn_astnode p - = dmnsn_new_astnode1(DMNSN_AST_GRADIENT, @$, $2); - $$ = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @$, p); - } -; - -PATTERN_TYPE: BLOCK_PATTERN_TYPE - | CONTINUOUS_PATTERN_TYPE -; - -/* Textures */ - -TEXTURE: "texture" "{" - TEXTURE_ITEMS - "}" - { $$ = $3; } -; - -TEXTURE_ITEMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_TEXTURE, @$); - } - | TEXTURE_ITEMS PIGMENT { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } - | TEXTURE_ITEMS FINISH { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } - | TEXTURE_ITEMS TRANSFORMATION { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -/* Pigments */ - -PIGMENT: "pigment" "{" - PIGMENT_BODY - "}" - { - $$ = $3; - } -; - -PIGMENT_BODY: PIGMENT_TYPE PIGMENT_MODIFIERS { - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, $1, $2); - } - | "checker" COLOR_LIST2 PIGMENT_MODIFIERS { - dmnsn_astnode checker = dmnsn_new_astleaf(DMNSN_AST_CHECKER, @1); - dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @1, - checker); - dmnsn_array_push($3.children, &$2); - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $3); - } - | "checker" PIGMENT_LIST2 PIGMENT_MODIFIERS { - dmnsn_astnode checker = dmnsn_new_astleaf(DMNSN_AST_CHECKER, @1); - dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @1, - checker); - dmnsn_array_push($3.children, &$2); - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $3); - } -; - -PIGMENT_TYPE: COLOR - | CONTINUOUS_PATTERN_TYPE - | "image_map" "{" - BITMAP_TYPE STRING - "}" - { - $$ = dmnsn_new_astnode2(DMNSN_AST_IMAGE_MAP, @$, $3, $4); - } - | "image_map" "{" - STRING - "}" - { - dmnsn_astnode type = dmnsn_new_astleaf(DMNSN_AST_PNG, @$); - $$ = dmnsn_new_astnode2(DMNSN_AST_IMAGE_MAP, @$, type, $3); - } -; - -BITMAP_TYPE: "png" { - $$ = dmnsn_new_astleaf(DMNSN_AST_PNG, @$); - } -; - -PIGMENT_MODIFIERS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_PIGMENT_MODIFIERS, @$); - } - | PIGMENT_MODIFIERS TRANSFORMATION { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } - | PIGMENT_MODIFIERS COLOR_MAP { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } - | PIGMENT_MODIFIERS PIGMENT_MAP { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } - | PIGMENT_MODIFIERS "quick_color" COLOR { - dmnsn_astnode quick_color - = dmnsn_new_astnode1(DMNSN_AST_QUICK_COLOR, @2, $3); - $$ = $1; - dmnsn_array_push($$.children, &quick_color); - } -; - -COLOR_LIST2: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_COLOR_LIST, @$); - } - | COLOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_COLOR_LIST, @$, $1); - } - | COLOR "," COLOR { - $$ = dmnsn_new_astnode2(DMNSN_AST_COLOR_LIST, @$, $1, $3); - } -; - -COLOR_MAP: "color_map" "{" - COLOR_MAP_ENTRIES - "}" - { - $$ = $3; - } -; - -COLOR_MAP_ENTRIES: COLOR_MAP_ENTRY { - $$ = dmnsn_new_astnode1(DMNSN_AST_COLOR_MAP, @$, $1); - } - | COLOR_MAP_ENTRIES COLOR_MAP_ENTRY { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -COLOR_MAP_ENTRY: "[" FLOAT "color" COLOR_BODY "]" { - $$ = dmnsn_new_astnode2(DMNSN_AST_COLOR_MAP_ENTRY, @$, $2, $4); - } -; - -PIGMENT_LIST2: PIGMENT { - $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT_LIST, @$, $1); - } - | PIGMENT PIGMENT { - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_LIST, @$, $1, $2); - } - | PIGMENT "," PIGMENT { - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_LIST, @$, $1, $3); - } -; - -PIGMENT_MAP: "pigment_map" "{" - PIGMENT_MAP_ENTRIES - "}" - { - $$ = $3; - } -; - -PIGMENT_MAP_ENTRIES: PIGMENT_MAP_ENTRY { - $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT_MAP, @$, $1); - } - | PIGMENT_MAP_ENTRIES PIGMENT_MAP_ENTRY { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -PIGMENT_MAP_ENTRY: "[" FLOAT PIGMENT_BODY "]" { - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_MAP_ENTRY, @$, - $2, $3); - } -; - -/* Finishes */ -FINISH: "finish" "{" - FINISH_ITEMS - "}" - { $$ = $3; } -; - -FINISH_ITEMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_FINISH, @$); - } - | FINISH_ITEMS "ambient" COLOR { - dmnsn_astnode ambient = dmnsn_new_astnode1(DMNSN_AST_AMBIENT, - @2, $3); - $$ = $1; - dmnsn_array_push($$.children, &ambient); - } - | FINISH_ITEMS "diffuse" FLOAT { - dmnsn_astnode diffuse = dmnsn_new_astnode1(DMNSN_AST_DIFFUSE, - @2, $3); - $$ = $1; - dmnsn_array_push($$.children, &diffuse); - } - | FINISH_ITEMS "phong" FLOAT { - dmnsn_astnode phong = dmnsn_new_astnode1(DMNSN_AST_PHONG, @2, $3); - $$ = $1; - dmnsn_array_push($$.children, &phong); - } - | FINISH_ITEMS "phong_size" FLOAT { - dmnsn_astnode phong_size - = dmnsn_new_astnode1(DMNSN_AST_PHONG_SIZE, @2, $3); - $$ = $1; - dmnsn_array_push($$.children, &phong_size); - } - | FINISH_ITEMS REFLECTION { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -REFLECTION: "reflection" "{" - COLOR - REFLECTION_ITEMS - "}" - { - ++*$3.refcount; - $$ = dmnsn_new_astnode3(DMNSN_AST_REFLECTION, @$, $3, $3, $4); - } - | "reflection" "{" - COLOR "," COLOR - REFLECTION_ITEMS - "}" - { - $$ = dmnsn_new_astnode3(DMNSN_AST_REFLECTION, @$, $3, $5, $6); - } -; - -REFLECTION_ITEMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_REFLECTION_ITEMS, @$); - } - | REFLECTION_ITEMS "falloff" FLOAT { - dmnsn_astnode falloff - = dmnsn_new_astnode1(DMNSN_AST_FALLOFF, @2, $3); - $$ = $1; - dmnsn_array_push($$.children, &falloff); - } -; - -/* Interiors */ -INTERIOR: "interior" "{" - INTERIOR_ITEMS - "}" - { $$ = $3; } -; - -INTERIOR_ITEMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_INTERIOR, @$); - } - | INTERIOR_ITEMS "ior" FLOAT { - dmnsn_astnode diffuse = dmnsn_new_astnode1(DMNSN_AST_IOR, - @2, $3); - $$ = $1; - dmnsn_array_push($$.children, &diffuse); - } -; - -/* Floats */ - -FLOAT: ARITH_EXPR { - $$ = dmnsn_eval_scalar($1, symtable); - dmnsn_delete_astnode($1); - - if ($$.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode($$); - YYERROR; - } - } -; - -INT: FLOAT { - $$ = $1; - if ($$.type == DMNSN_AST_FLOAT) { - dmnsn_diagnostic(@$, "WARNING: float rounded to integer"); - } - } -; - -FLOAT_LITERAL: "integer" { - dmnsn_astnode string = dmnsn_new_astleaf(DMNSN_AST_STRING, @$); - string.ptr = $1; - $$ = dmnsn_new_astnode1(DMNSN_AST_VAL, @$, string); - } - | "float" { - dmnsn_astnode string = dmnsn_new_astleaf(DMNSN_AST_STRING, @$); - string.ptr = $1; - $$ = dmnsn_new_astnode1(DMNSN_AST_VAL, @$, string); - } -; - -/* Vectors */ - -VECTOR: ARITH_EXPR { - $$ = dmnsn_eval_vector($1, symtable); - dmnsn_delete_astnode($1); - - if ($$.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode($$); - YYERROR; - } - } -; - -VECTOR_LITERAL: "<" ARITH_EXPR "," ARITH_EXPR ">" { - $$ = dmnsn_new_astnode2(DMNSN_AST_VECTOR, @$, $2, $4); - } - | "<" ARITH_EXPR "," ARITH_EXPR "," ARITH_EXPR ">" { - $$ = dmnsn_new_astnode3(DMNSN_AST_VECTOR, @$, $2, $4, $6); - } - | "<" ARITH_EXPR "," ARITH_EXPR "," ARITH_EXPR "," - ARITH_EXPR ">" { - $$ = dmnsn_new_astnode4(DMNSN_AST_VECTOR, @$, $2, $4, $6, $8); - } - | "<" ARITH_EXPR "," ARITH_EXPR "," ARITH_EXPR "," - ARITH_EXPR "," ARITH_EXPR ">" { - $$ = dmnsn_new_astnode5(DMNSN_AST_VECTOR, @$, - $2, $4, $6, $8, $10); - } -; - -/* Generalized arithmetic expressions */ - -ARITH_EXPR: FLOAT_LITERAL - | VECTOR_LITERAL - | ARITH_EXPR "+" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_ADD, @$, $1, $3); - } - | ARITH_EXPR "-" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_SUB, @$, $1, $3); - } - | ARITH_EXPR "*" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $1, $3); - } - | ARITH_EXPR "/" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_DIV, @$, $1, $3); - } - | "+" ARITH_EXPR %prec DMNSN_T_NEGATE { $$ = $2; } - | "-" ARITH_EXPR %prec DMNSN_T_NEGATE { - $$ = dmnsn_new_astnode1(DMNSN_AST_NEGATE, @$, $2); - } - | ARITH_EXPR "." "x" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_X, @$, $1); - } - | ARITH_EXPR "." "u" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_X, @$, $1); - } - | ARITH_EXPR "." "red" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_X, @$, $1); - } - | ARITH_EXPR "." "y" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Y, @$, $1); - } - | ARITH_EXPR "." "v" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Y, @$, $1); - } - | ARITH_EXPR "." "green" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Y, @$, $1); - } - | ARITH_EXPR "." "z" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Z, @$, $1); - } - | ARITH_EXPR "." "blue" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_Z, @$, $1); - } - | ARITH_EXPR "." "t" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_T, @$, $1); - } - | ARITH_EXPR "." "filter" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_T, @$, $1); - } - | ARITH_EXPR "." "transmit" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DOT_TRANSMIT, @$, $1); - } - | "(" ARITH_EXPR ")" %dprec 2 { $$ = $2; } - | "(" CONDITIONAL "?" ARITH_EXPR ":" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode3(DMNSN_AST_TERNARY, @$, $2, $4, $6); - } - | "abs" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ABS, @$, $3); - } - | "acos" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ACOS, @$, $3); - } - | "acosh" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ACOSH, @$, $3); - } - | "asc" "(" STRING ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ASC, @$, $3); - } - | "asin" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ASIN, @$, $3); - } - | "asinh" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ASINH, @$, $3); - } - | "atan" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ATAN, @$, $3); - } - | "atan2" "(" ARITH_EXPR "," ARITH_EXPR ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_ATAN2, @$, $3, $5); - } - | "atanh" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_ATANH, @$, $3); - } - | "ceil" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_CEIL, @$, $3); - } - | "cos" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_COS, @$, $3); - } - | "cosh" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_COSH, @$, $3); - } - | "degrees" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_DEGREES, @$, $3); - } - | "div" "(" ARITH_EXPR "," ARITH_EXPR ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_INT_DIV, @$, $3, $5); - } - | "exp" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_EXP, @$, $3); - } - | "floor" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_FLOOR, @$, $3); - } - | "int" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_INT, @$, $3); - } - | "ln" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_LN, @$, $3); - } - | "log" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_LOG, @$, $3); - } - | "max" "(" MAX_LIST ")" { - $$ = $3; - } - | "min" "(" MIN_LIST ")" { - $$ = $3; - } - | "mod" "(" ARITH_EXPR "," ARITH_EXPR ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_MOD, @$, $3, $5); - } - | "pow" "(" ARITH_EXPR "," ARITH_EXPR ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_POW, @$, $3, $5); - } - | "radians" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_RADIANS, @$, $3); - } - | "sin" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_SIN, @$, $3); - } - | "sinh" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_SINH, @$, $3); - } - | "sqrt" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_SQRT, @$, $3); - } - | "strcmp" "(" STRING "," STRING ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_STRCMP, @$, $3, $5); - } - | "strlen" "(" STRING ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_STRLEN, @$, $3); - } - | "tan" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_TAN, @$, $3); - } - | "tanh" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_TANH, @$, $3); - } - | "val" "(" STRING ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_VAL, @$, $3); - } - | "vaxis_rotate" "(" ARITH_EXPR "," ARITH_EXPR "," ARITH_EXPR ")" { - dmnsn_astnode axis - = dmnsn_new_astnode1(DMNSN_AST_VNORMALIZE, @$, $5); - axis = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $7, axis); - $$ = dmnsn_new_astnode2(DMNSN_AST_VAXIS_ROTATE, @$, $3, axis); - } - | "vcross" "(" ARITH_EXPR "," ARITH_EXPR ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_VCROSS, @$, $3, $5); - } - | "vdot" "(" ARITH_EXPR "," ARITH_EXPR ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_VDOT, @$, $3, $5); - } - | "vlength" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_VLENGTH, @$, $3); - } - | "vnormalize" "(" ARITH_EXPR ")" { - $$ = dmnsn_new_astnode1(DMNSN_AST_VNORMALIZE, @$, $3); - } - | "vrotate" "(" ARITH_EXPR "," ARITH_EXPR ")" { - $$ = dmnsn_new_astnode2(DMNSN_AST_VROTATE, @$, $3, $5); - } - | "image_height" { - $$ = dmnsn_new_astleaf(DMNSN_AST_IDENTIFIER, @$); - $$.ptr = dmnsn_strdup("image_height"); - } - | "image_width" { - $$ = dmnsn_new_astleaf(DMNSN_AST_IDENTIFIER, @$); - $$.ptr = dmnsn_strdup("image_width"); - } - | "pi" { $$ = dmnsn_new_astleaf(DMNSN_AST_PI, @$); } - | "true" { $$ = dmnsn_new_astleaf(DMNSN_AST_TRUE, @$); } - | "on" { $$ = dmnsn_new_astleaf(DMNSN_AST_TRUE, @$); } - | "yes" { $$ = dmnsn_new_astleaf(DMNSN_AST_TRUE, @$); } - | "false" { $$ = dmnsn_new_astleaf(DMNSN_AST_FALSE, @$); } - | "off" { $$ = dmnsn_new_astleaf(DMNSN_AST_FALSE, @$); } - | "no" { $$ = dmnsn_new_astleaf(DMNSN_AST_FALSE, @$); } - | "x" { $$ = dmnsn_new_astleaf(DMNSN_AST_X, @$); } - | "u" { $$ = dmnsn_new_astleaf(DMNSN_AST_X, @$); } - | "y" { $$ = dmnsn_new_astleaf(DMNSN_AST_Y, @$); } - | "v" { $$ = dmnsn_new_astleaf(DMNSN_AST_Y, @$); } - | "z" { $$ = dmnsn_new_astleaf(DMNSN_AST_Z, @$); } - | "t" { $$ = dmnsn_new_astleaf(DMNSN_AST_T, @$); } - | IDENTIFIER -; - -MAX_LIST: ARITH_EXPR "," ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MAX, @$, $1, $3); - } - | MAX_LIST "," ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MAX, @$, $1, $3); - } -; - -MIN_LIST: ARITH_EXPR "," ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MIN, @$, $1, $3); - } - | MIN_LIST "," ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_MIN, @$, $1, $3); - } -; - -CONDITIONAL: ARITH_EXPR { - /* Force the expression to be evaluated logically */ - dmnsn_astnode zero = dmnsn_new_ast_integer(0); - $$ = dmnsn_new_astnode2(DMNSN_AST_OR, @$, zero, $1); - } - | ARITH_EXPR "=" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_EQUAL, @$, $1, $3); - } - | ARITH_EXPR "!=" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_NOT_EQUAL, @$, $1, $3); - } - | ARITH_EXPR "<" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_LESS, @$, $1, $3); - } - | ARITH_EXPR "<=" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_LESS_EQUAL, @$, $1, $3); - } - | ARITH_EXPR ">" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_GREATER, @$, $1, $3); - } - | ARITH_EXPR ">=" ARITH_EXPR { - $$ = dmnsn_new_astnode2(DMNSN_AST_GREATER_EQUAL, @$, $1, $3); - } - | CONDITIONAL "&" CONDITIONAL { - $$ = dmnsn_new_astnode2(DMNSN_AST_AND, @$, $1, $3); - } - | CONDITIONAL "|" CONDITIONAL { - $$ = dmnsn_new_astnode2(DMNSN_AST_OR, @$, $1, $3); - } - | "(" CONDITIONAL ")" %dprec 1 { - $$ = $2; - } - | "!" CONDITIONAL { - $$ = dmnsn_new_astnode1(DMNSN_AST_NOT, @$, $2); - } -; - -/* Colors */ - -COLOR: COLOR_BODY { - $$ = $1; - } - | "color" COLOR_BODY { - $$ = $2; - } -; - -COLOR_BODY: COLOR_VECTOR %dprec 1 - | COLOR_KEYWORD_GROUP %dprec 2 -; - -COLOR_VECTOR: "rgb" VECTOR { - dmnsn_astnode f, t; - dmnsn_array_get($2.children, 3, &f); - dmnsn_array_get($2.children, 4, &t); - dmnsn_delete_astnode(f); - dmnsn_delete_astnode(t); - - dmnsn_array_resize($2.children, 3); - - $$ = dmnsn_eval_vector($2, symtable); - dmnsn_delete_astnode($2); - } - | "rgbf" VECTOR { - dmnsn_astnode t; - dmnsn_array_get($2.children, 4, &t); - dmnsn_delete_astnode(t); - - dmnsn_array_resize($2.children, 4); - - $$ = dmnsn_eval_vector($2, symtable); - dmnsn_delete_astnode($2); - } - | "rgbt" VECTOR { - /* Chop off the fifth component */ - dmnsn_astnode t; - dmnsn_array_get($2.children, 4, &t); - dmnsn_delete_astnode(t); - - dmnsn_array_resize($2.children, 4); - - $$ = dmnsn_eval_vector($2, symtable); - dmnsn_delete_astnode($2); - - /* Swap the transmit and filter components */ - dmnsn_astnode temp; - dmnsn_array_get($$.children, 4, &temp); - dmnsn_array_set($$.children, 4, dmnsn_array_at($$.children, 3)); - dmnsn_array_set($$.children, 3, &temp); - } - | "rgbft" VECTOR { $$ = $2; } - | VECTOR -; - -COLOR_KEYWORD_GROUP: COLOR_KEYWORD_GROUP_INIT COLOR_KEYWORD_ITEM - | COLOR_KEYWORD_GROUP COLOR_KEYWORD_ITEM -; - -COLOR_KEYWORD_GROUP_INIT: /* empty */ { - dmnsn_astnode zero = dmnsn_new_ast_integer(0); - $$ = dmnsn_eval_vector(zero, symtable); - dmnsn_delete_astnode(zero); - } -; - -COLOR_KEYWORD_ITEM: IDENTIFIER { - dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, $1.ptr); - if (!symbol) { - dmnsn_diagnostic(@1, "unbound identifier '%s'", - (const char *)$1.ptr); - dmnsn_delete_astnode($1); - YYERROR; - } else { - dmnsn_astnode eval = dmnsn_eval_vector(*symbol, symtable); - if (eval.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode($1); - YYERROR; - } - - dmnsn_copy_children($<astnode>0, eval); - dmnsn_delete_astnode(eval); - } - - dmnsn_delete_astnode($1); - } - | "red" FLOAT { - dmnsn_astnode old; - dmnsn_array_get($<astnode>0.children, 0, &old); - dmnsn_array_set($<astnode>0.children, 0, &$2); - dmnsn_delete_astnode(old); - } - | "green" FLOAT { - dmnsn_astnode old; - dmnsn_array_get($<astnode>0.children, 1, &old); - dmnsn_array_set($<astnode>0.children, 1, &$2); - dmnsn_delete_astnode(old); - } - | "blue" FLOAT { - dmnsn_astnode old; - dmnsn_array_get($<astnode>0.children, 2, &old); - dmnsn_array_set($<astnode>0.children, 2, &$2); - dmnsn_delete_astnode(old); - } - | "filter" FLOAT { - dmnsn_astnode old; - dmnsn_array_get($<astnode>0.children, 3, &old); - dmnsn_array_set($<astnode>0.children, 3, &$2); - dmnsn_delete_astnode(old); - } - | "transmit" FLOAT { - dmnsn_astnode old; - dmnsn_array_get($<astnode>0.children, 4, &old); - dmnsn_array_set($<astnode>0.children, 4, &$2); - dmnsn_delete_astnode(old); - } -; diff --git a/dimension/common.terminals b/dimension/common.terminals deleted file mode 100644 index 567267b..0000000 --- a/dimension/common.terminals +++ /dev/null @@ -1,526 +0,0 @@ -#line 2 "common.terminals" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -%token DMNSN_T_EOF 0 "end-of-file" -%token DMNSN_T_LEX_ERROR "parse error" - -/* Punctuation */ -%token DMNSN_T_LBRACE "{" -%token DMNSN_T_RBRACE "}" -%token DMNSN_T_LPAREN "(" -%token DMNSN_T_RPAREN ")" -%token DMNSN_T_LBRACKET "[" -%token DMNSN_T_RBRACKET "]" -%token DMNSN_T_PLUS "+" -%token DMNSN_T_MINUS "-" -%token DMNSN_T_STAR "*" -%token DMNSN_T_SLASH "/" -%token DMNSN_T_COMMA "," -%token DMNSN_T_SEMICOLON ";" -%token DMNSN_T_QUESTION "?" -%token DMNSN_T_COLON ":" -%token DMNSN_T_AND "&" -%token DMNSN_T_DOT "." -%token DMNSN_T_PIPE "|" -%token DMNSN_T_LESS "<" -%token DMNSN_T_GREATER ">" -%token DMNSN_T_BANG "!" -%token DMNSN_T_EQUALS "=" -%token DMNSN_T_LESS_EQUAL "<=" -%token DMNSN_T_GREATER_EQUAL ">=" -%token DMNSN_T_NOT_EQUAL "!=" - -/* Operators */ -%left "|" -%left "&" -%left "!" -%left "=" "!=" "<" "<=" ">" ">=" -%left "+" "-" -%left "*" "/" -%left "." -%left DMNSN_T_NEGATE - -/* Numeric values */ -%token <value> DMNSN_T_INTEGER "integer" -%token <value> DMNSN_T_FLOAT "float" - -/* Keywords */ -%token DMNSN_T_AA_LEVEL -%token DMNSN_T_AA_THRESHOLD -%token DMNSN_T_ABS "abs" -%token DMNSN_T_ABSORPTION -%token DMNSN_T_ACCURACY -%token DMNSN_T_ACOS "acos" -%token DMNSN_T_ACOSH "acosh" -%token DMNSN_T_ADAPTIVE -%token DMNSN_T_ADC_BAILOUT "adc_bailout" -%token DMNSN_T_AGATE -%token DMNSN_T_AGATE_TURB -%token DMNSN_T_ALL -%token DMNSN_T_ALL_INTERSECTIONS -%token DMNSN_T_ALPHA -%token DMNSN_T_ALTITUDE -%token DMNSN_T_ALWAYS_SAMPLE -%token DMNSN_T_AMBIENT "ambient" -%token DMNSN_T_AMBIENT_LIGHT "ambient_light" -%token DMNSN_T_ANGLE "angle" -%token DMNSN_T_APERTURE -%token DMNSN_T_APPEND -%token DMNSN_T_ARC_ANGLE -%token DMNSN_T_AREA_LIGHT -%token DMNSN_T_ARRAY -%token DMNSN_T_ASC "asc" -%token DMNSN_T_ASCII "ascii" -%token DMNSN_T_ASIN "asin" -%token DMNSN_T_ASINH "asinh" -%token DMNSN_T_ASSUMED_GAMMA "assumed_gamma" -%token DMNSN_T_ATAN "atan" -%token DMNSN_T_ATAN2 "atan2" -%token DMNSN_T_ATANH "atanh" -%token DMNSN_T_AUTOSTOP -%token DMNSN_T_AVERAGE -%token DMNSN_T_B_SPLINE -%token DMNSN_T_BACKGROUND "background" -%token DMNSN_T_BEZIER_SPLINE -%token DMNSN_T_BICUBIC_PATCH -%token DMNSN_T_BLACK_HOLE -%token DMNSN_T_BLOB -%token DMNSN_T_BLUE "blue" -%token DMNSN_T_BLUR_SAMPLES -%token DMNSN_T_BOUNDED_BY -%token DMNSN_T_BOX "box" -%token DMNSN_T_BOXED -%token DMNSN_T_BOZO -%token DMNSN_T_BRICK -%token DMNSN_T_BRICK_SIZE -%token DMNSN_T_BRIGHTNESS -%token DMNSN_T_BRILLIANCE -%token DMNSN_T_BUMP_MAP -%token DMNSN_T_BUMP_SIZE -%token DMNSN_T_BUMPS -%token DMNSN_T_CAMERA "camera" -%token DMNSN_T_CAUSTICS -%token DMNSN_T_CEIL "ceil" -%token DMNSN_T_CELLS -%token DMNSN_T_CHARSET "charset" -%token DMNSN_T_CHECKER "checker" -%token DMNSN_T_CHR -%token DMNSN_T_CIRCULAR -%token DMNSN_T_CLIPPED_BY -%token DMNSN_T_CLOCK -%token DMNSN_T_CLOCK_DELTA -%token DMNSN_T_CLOCK_ON -%token DMNSN_T_COLLECT -%token DMNSN_T_COLOR "color" -%token DMNSN_T_COLOR_MAP "color_map" -%token DMNSN_T_COMPONENT -%token DMNSN_T_COMPOSITE -%token DMNSN_T_CONCAT -%token DMNSN_T_CONE "cone" -%token DMNSN_T_CONFIDENCE -%token DMNSN_T_CONIC_SWEEP -%token DMNSN_T_CONSERVE_ENERGY -%token DMNSN_T_CONTAINED_BY -%token DMNSN_T_CONTROL0 -%token DMNSN_T_CONTROL1 -%token DMNSN_T_COORDS -%token DMNSN_T_COS "cos" -%token DMNSN_T_COSH "cosh" -%token DMNSN_T_COUNT -%token DMNSN_T_CRACKLE -%token DMNSN_T_CRAND -%token DMNSN_T_CUBE -%token DMNSN_T_CUBIC -%token DMNSN_T_CUBIC_SPLINE -%token DMNSN_T_CUBIC_WAVE -%token DMNSN_T_CUTAWAY_TEXTURES -%token DMNSN_T_CYLINDER "cylinder" -%token DMNSN_T_CYLINDRICAL -%token DMNSN_T_DEFINED -%token DMNSN_T_DEGREES "degrees" -%token DMNSN_T_DENSITY -%token DMNSN_T_DENSITY_FILE -%token DMNSN_T_DENSITY_MAP -%token DMNSN_T_DENTS -%token DMNSN_T_DF3 -%token DMNSN_T_DIFFERENCE "difference" -%token DMNSN_T_DIFFUSE "diffuse" -%token DMNSN_T_DIMENSION_SIZE -%token DMNSN_T_DIMENSIONS -%token DMNSN_T_DIRECTION "direction" -%token DMNSN_T_DISC -%token DMNSN_T_DISPERSION -%token DMNSN_T_DISPERSION_SAMPLES -%token DMNSN_T_DIST_EXP -%token DMNSN_T_DISTANCE -%token DMNSN_T_DIV "div" -%token DMNSN_T_DOUBLE_ILLUMINATE -%token DMNSN_T_ECCENTRICITY -%token DMNSN_T_EMISSION -%token DMNSN_T_ERROR_BOUND -%token DMNSN_T_EVALUATE -%token DMNSN_T_EXP "exp" -%token DMNSN_T_EXPAND_THRESHOLDS -%token DMNSN_T_EXPONENT -%token DMNSN_T_EXTERIOR -%token DMNSN_T_EXTINCTION -%token DMNSN_T_FACE_INDICES -%token DMNSN_T_FACETS -%token DMNSN_T_FADE_COLOR -%token DMNSN_T_FADE_DISTANCE -%token DMNSN_T_FADE_POWER -%token DMNSN_T_FALLOFF "falloff" -%token DMNSN_T_FALLOFF_ANGLE -%token DMNSN_T_FALSE "false" -%token DMNSN_T_FILE_EXISTS -%token DMNSN_T_FILTER "filter" -%token DMNSN_T_FINAL_CLOCK -%token DMNSN_T_FINAL_FRAME -%token DMNSN_T_FINISH "finish" -%token DMNSN_T_FISHEYE -%token DMNSN_T_FLATNESS -%token DMNSN_T_FLIP -%token DMNSN_T_FLOOR "floor" -%token DMNSN_T_FOCAL_POINT -%token DMNSN_T_FOG -%token DMNSN_T_FOG_ALT -%token DMNSN_T_FOG_OFFSET -%token DMNSN_T_FOG_TYPE -%token DMNSN_T_FORM -%token DMNSN_T_FRAME_NUMBER -%token DMNSN_T_FREQUENCY -%token DMNSN_T_FRESNEL -%token DMNSN_T_FUNCTION -%token DMNSN_T_GATHER -%token DMNSN_T_GIF -%token DMNSN_T_GLOBAL_LIGHTS -%token DMNSN_T_GLOBAL_SETTINGS "global_settings" -%token DMNSN_T_GRADIENT "gradient" -%token DMNSN_T_GRANITE -%token DMNSN_T_GRAY "gray" -%token DMNSN_T_GRAY_THRESHOLD -%token DMNSN_T_GREEN "green" -%token DMNSN_T_HEIGHT_FIELD -%token DMNSN_T_HEXAGON -%token DMNSN_T_HF_GRAY_16 -%token DMNSN_T_HIERARCHY -%token DMNSN_T_HYPERCOMPLEX -%token DMNSN_T_HOLLOW -%token DMNSN_T_IFF -%token DMNSN_T_IMAGE_HEIGHT "image_height" -%token DMNSN_T_IMAGE_MAP "image_map" -%token DMNSN_T_IMAGE_PATTERN -%token DMNSN_T_IMAGE_WIDTH "image_width" -%token DMNSN_T_INITIAL_CLOCK -%token DMNSN_T_INITIAL_FRAME -%token DMNSN_T_INSIDE -%token DMNSN_T_INSIDE_VECTOR -%token DMNSN_T_INT "int" -%token DMNSN_T_INTERIOR "interior" -%token DMNSN_T_INTERIOR_TEXTURE -%token DMNSN_T_INTERNAL -%token DMNSN_T_INTERPOLATE -%token DMNSN_T_INTERSECTION "intersection" -%token DMNSN_T_INTERVALS -%token DMNSN_T_INVERSE "inverse" -%token DMNSN_T_IOR "ior" -%token DMNSN_T_IRID -%token DMNSN_T_IRID_WAVELENGTH -%token DMNSN_T_ISOSURFACE -%token DMNSN_T_JITTER -%token DMNSN_T_JPEG -%token DMNSN_T_JULIA -%token DMNSN_T_JULIA_FRACTAL -%token DMNSN_T_LAMBDA -%token DMNSN_T_LATHE -%token DMNSN_T_LEOPARD -%token DMNSN_T_LIGHT_GROUP -%token DMNSN_T_LIGHT_SOURCE "light_source" -%token DMNSN_T_LINEAR_SPLINE -%token DMNSN_T_LINEAR_SWEEP -%token DMNSN_T_LN "ln" -%token DMNSN_T_LOAD_FILE -%token DMNSN_T_LOCATION "location" -%token DMNSN_T_LOG "log" -%token DMNSN_T_LOOK_AT "look_at" -%token DMNSN_T_LOOKS_LIKE -%token DMNSN_T_LOW_ERROR_FACTOR -%token DMNSN_T_MAGNET -%token DMNSN_T_MAJOR_RADIUS -%token DMNSN_T_MANDEL -%token DMNSN_T_MAP_TYPE -%token DMNSN_T_MARBLE -%token DMNSN_T_MATERIAL -%token DMNSN_T_MATERIAL_MAP -%token DMNSN_T_MATRIX "matrix" -%token DMNSN_T_MAX "max" -%token DMNSN_T_MAX_EXTENT -%token DMNSN_T_MAX_GRADIENT -%token DMNSN_T_MAX_INTERSECTIONS "max_intersections" -%token DMNSN_T_MAX_ITERATION -%token DMNSN_T_MAX_SAMPLE -%token DMNSN_T_MAX_TRACE -%token DMNSN_T_MAX_TRACE_LEVEL "max_trace_level" -%token DMNSN_T_MEDIA -%token DMNSN_T_MEDIA_ATTENUATION -%token DMNSN_T_MEDIA_INTERACTION -%token DMNSN_T_MERGE "merge" -%token DMNSN_T_MESH -%token DMNSN_T_MESH2 -%token DMNSN_T_METALLIC -%token DMNSN_T_METHOD -%token DMNSN_T_METRIC -%token DMNSN_T_MIN "min" -%token DMNSN_T_MIN_EXTENT -%token DMNSN_T_MINIMUM_REUSE -%token DMNSN_T_MOD "mod" -%token DMNSN_T_MORTAR -%token DMNSN_T_NATURAL_SPLINE -%token DMNSN_T_NEAREST_COUNT -%token DMNSN_T_NO "no" -%token DMNSN_T_NO_BUMP_SCALE -%token DMNSN_T_NO_IMAGE -%token DMNSN_T_NO_REFLECTION -%token DMNSN_T_NO_SHADOW -%token DMNSN_T_NOISE_GENERATOR -%token DMNSN_T_NORMAL -%token DMNSN_T_NORMAL_INDICES -%token DMNSN_T_NORMAL_MAP -%token DMNSN_T_NORMAL_VECTORS -%token DMNSN_T_NUMBER_OF_WAVES -%token DMNSN_T_OBJECT "object" -%token DMNSN_T_OCTAVES -%token DMNSN_T_OFF "off" -%token DMNSN_T_OFFSET -%token DMNSN_T_OMEGA -%token DMNSN_T_OMNIMAX -%token DMNSN_T_ON "on" -%token DMNSN_T_ONCE -%token DMNSN_T_ONION -%token DMNSN_T_OPEN "open" -%token DMNSN_T_ORIENT -%token DMNSN_T_ORIENTATION -%token DMNSN_T_ORTHOGRAPHIC -%token DMNSN_T_PANORAMIC -%token DMNSN_T_PARALLEL -%token DMNSN_T_PARAMETRIC -%token DMNSN_T_PASS_THROUGH -%token DMNSN_T_PATTERN -%token DMNSN_T_PERSPECTIVE "perspective" -%token DMNSN_T_PGM -%token DMNSN_T_PHASE -%token DMNSN_T_PHONG "phong" -%token DMNSN_T_PHONG_SIZE "phong_size" -%token DMNSN_T_PHOTONS -%token DMNSN_T_PI "pi" -%token DMNSN_T_PIGMENT "pigment" -%token DMNSN_T_PIGMENT_MAP "pigment_map" -%token DMNSN_T_PIGMENT_PATTERN -%token DMNSN_T_PLANAR -%token DMNSN_T_PLANE "plane" -%token DMNSN_T_PNG "png" -%token DMNSN_T_POINT_AT -%token DMNSN_T_POLY -%token DMNSN_T_POLY_WAVE -%token DMNSN_T_POLYGON -%token DMNSN_T_POT -%token DMNSN_T_POW "pow" -%token DMNSN_T_PPM -%token DMNSN_T_PRECISION -%token DMNSN_T_PRECOMPUTE -%token DMNSN_T_PRETRACE_END -%token DMNSN_T_PRETRACE_START -%token DMNSN_T_PRISM -%token DMNSN_T_PROD -%token DMNSN_T_PROJECTED_THROUGH -%token DMNSN_T_PWR -%token DMNSN_T_QUADRATIC_SPLINE -%token DMNSN_T_QUADRIC -%token DMNSN_T_QUARTIC -%token DMNSN_T_QUATERNION -%token DMNSN_T_QUICK_COLOR "quick_color" -%token DMNSN_T_QUILTED -%token DMNSN_T_RADIAL -%token DMNSN_T_RADIANS "radians" -%token DMNSN_T_RADIOSITY -%token DMNSN_T_RADIUS -%token DMNSN_T_RAINBOW -%token DMNSN_T_RAMP_WAVE -%token DMNSN_T_RAND -%token DMNSN_T_RATIO -%token DMNSN_T_RECIPROCAL -%token DMNSN_T_RECURSION_LIMIT -%token DMNSN_T_RED "red" -%token DMNSN_T_REFLECTION "reflection" -%token DMNSN_T_REFLECTION_EXPONENT -%token DMNSN_T_REFRACTION -%token DMNSN_T_REPEAT -%token DMNSN_T_RGB "rgb" -%token DMNSN_T_RGBF "rgbf" -%token DMNSN_T_RGBFT "rgbft" -%token DMNSN_T_RGBT "rgbt" -%token DMNSN_T_RIGHT "right" -%token DMNSN_T_RIPPLES -%token DMNSN_T_ROTATE "rotate" -%token DMNSN_T_ROUGHNESS -%token DMNSN_T_SAMPLES -%token DMNSN_T_SAVE_FILE -%token DMNSN_T_SCALE "scale" -%token DMNSN_T_SCALLOP_WAVE -%token DMNSN_T_SCATTERING -%token DMNSN_T_SEED -%token DMNSN_T_SELECT -%token DMNSN_T_SHADOWLESS -%token DMNSN_T_SIN "sin" -%token DMNSN_T_SINE_WAVE -%token DMNSN_T_SINH "sinh" -%token DMNSN_T_SIZE -%token DMNSN_T_SKY "sky" -%token DMNSN_T_SKY_SPHERE "sky_sphere" -%token DMNSN_T_SLICE -%token DMNSN_T_SLOPE -%token DMNSN_T_SLOPE_MAP -%token DMNSN_T_SMOOTH -%token DMNSN_T_SMOOTH_TRIANGLE -%token DMNSN_T_SOLID -%token DMNSN_T_SOR -%token DMNSN_T_SPACING -%token DMNSN_T_SPECULAR -%token DMNSN_T_SPHERE "sphere" -%token DMNSN_T_SPHERE_SWEEP -%token DMNSN_T_SPHERICAL -%token DMNSN_T_SPIRAL1 -%token DMNSN_T_SPIRAL2 -%token DMNSN_T_SPLINE -%token DMNSN_T_SPLIT_UNION -%token DMNSN_T_SPOTLIGHT -%token DMNSN_T_SPOTTED -%token DMNSN_T_SQR -%token DMNSN_T_SQRT "sqrt" -%token DMNSN_T_STR -%token DMNSN_T_STRCMP "strcmp" -%token DMNSN_T_STRENGTH -%token DMNSN_T_STRLEN "strlen" -%token DMNSN_T_STRLWR -%token DMNSN_T_STRUPR -%token DMNSN_T_STURM "sturm" -%token DMNSN_T_SUBSTR -%token DMNSN_T_SUM -%token DMNSN_T_SUPERELLIPSOID -%token DMNSN_T_SYS "sys" -%token DMNSN_T_T "t" -%token DMNSN_T_TAN "tan" -%token DMNSN_T_TANH "tanh" -%token DMNSN_T_TARGET -%token DMNSN_T_TEXT -%token DMNSN_T_TEXTURE "texture" -%token DMNSN_T_TEXTURE_LIST -%token DMNSN_T_TEXTURE_MAP -%token DMNSN_T_TGA -%token DMNSN_T_THICKNESS -%token DMNSN_T_THRESHOLD -%token DMNSN_T_TIFF -%token DMNSN_T_TIGHTNESS -%token DMNSN_T_TILE2 -%token DMNSN_T_TILES -%token DMNSN_T_TOLERANCE -%token DMNSN_T_TOROIDAL -%token DMNSN_T_TORUS "torus" -%token DMNSN_T_TRACE -%token DMNSN_T_TRANSFORM "transform" -%token DMNSN_T_TRANSLATE "translate" -%token DMNSN_T_TRANSMIT "transmit" -%token DMNSN_T_TRIANGLE -%token DMNSN_T_TRIANGLE_WAVE -%token DMNSN_T_TRUE "true" -%token DMNSN_T_TTF -%token DMNSN_T_TURB_DEPTH -%token DMNSN_T_TURBULENCE -%token DMNSN_T_TYPE -%token DMNSN_T_U "u" -%token DMNSN_T_U_STEPS -%token DMNSN_T_ULTRA_WIDE_ANGLE -%token DMNSN_T_UNION "union" -%token DMNSN_T_UP "up" -%token DMNSN_T_USE_ALPHA -%token DMNSN_T_USE_COLOR -%token DMNSN_T_USE_INDEX -%token DMNSN_T_UTF8 "utf8" -%token DMNSN_T_UV_INDICES -%token DMNSN_T_UV_MAPPING -%token DMNSN_T_UV_VECTORS -%token DMNSN_T_V "v" -%token DMNSN_T_V_STEPS -%token DMNSN_T_VAL "val" -%token DMNSN_T_VARIANCE -%token DMNSN_T_VAXIS_ROTATE "vaxis_rotate" -%token DMNSN_T_VCROSS "vcross" -%token DMNSN_T_VDOT "vdot" -%token DMNSN_T_VERTEX_VECTORS -%token DMNSN_T_VLENGTH "vlength" -%token DMNSN_T_VNORMALIZE "vnormalize" -%token DMNSN_T_VROTATE "vrotate" -%token DMNSN_T_VSTR -%token DMNSN_T_VTURBULENCE -%token DMNSN_T_WARP -%token DMNSN_T_WATER_LEVEL -%token DMNSN_T_WAVES -%token DMNSN_T_WIDTH -%token DMNSN_T_WOOD -%token DMNSN_T_WRINKLES -%token DMNSN_T_X "x" -%token DMNSN_T_Y "y" -%token DMNSN_T_YES "yes" -%token DMNSN_T_Z "z" - -/* Directives (#declare etc.) */ -%token DMNSN_T_BREAK "#break" -%token DMNSN_T_CASE "#case" -%token DMNSN_T_DEBUG "#debug" -%token DMNSN_T_DECLARE "#declare" -%token DMNSN_T_DEFAULT "#default" -%token DMNSN_T_ELSE "#else" -%token DMNSN_T_END "#end" -%token DMNSN_T_ERROR "#error" -%token DMNSN_T_FCLOSE "#fclose" -%token DMNSN_T_FOPEN "#fopen" -%token DMNSN_T_IF "#if" -%token DMNSN_T_IFDEF "#ifdef" -%token DMNSN_T_IFNDEF "#ifndef" -%token DMNSN_T_INCLUDE "#include" -%token DMNSN_T_LOCAL "#local" -%token DMNSN_T_MACRO "#macro" -%token DMNSN_T_RANGE "#range" -%token DMNSN_T_READ "#read" -%token DMNSN_T_RENDER "#render" -%token DMNSN_T_STATISTICS "#statistics" -%token DMNSN_T_SWITCH "#switch" -%token DMNSN_T_UNDEF "#undef" -%token DMNSN_T_VERSION "#version" -%token DMNSN_T_WARNING "#warning" -%token DMNSN_T_WHILE "#while" -%token DMNSN_T_WRITE "#write" - -/* Identifiers */ -%token <value> DMNSN_T_IDENTIFIER "identifier" - -/* Strings */ -%token <value> DMNSN_T_STRING "string" diff --git a/dimension/directives.declarations b/dimension/directives.declarations deleted file mode 100644 index 0cb62e9..0000000 --- a/dimension/directives.declarations +++ /dev/null @@ -1,29 +0,0 @@ -#line 2 "directives.declarations" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -%name-prefix "dmnsn_ld_yy" - -%expect 19 -%expect-rr 6 - -%parse-param {const char *filename} -%parse-param {void *yyscanner} -%parse-param {dmnsn_symbol_table *symtable} diff --git a/dimension/directives.nonterminals b/dimension/directives.nonterminals deleted file mode 100644 index 361e81b..0000000 --- a/dimension/directives.nonterminals +++ /dev/null @@ -1,27 +0,0 @@ -#line 2 "directives.nonterminals" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -%type <astnode> RVALUE -%type <astnode> DECL_PARAMS -%type <astnode> DECL_PARAM_LIST -%type <astnode> PARAMS -%type <astnode> PARAM_LIST -%type <astnode> PARAM diff --git a/dimension/directives.prologue b/dimension/directives.prologue deleted file mode 100644 index d94d5af..0000000 --- a/dimension/directives.prologue +++ /dev/null @@ -1,35 +0,0 @@ -#line 2 "directives.prologue" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -void -yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, - dmnsn_symbol_table *symtable, const char *str) -{ - dmnsn_diagnostic(*locp, "%s", str); -} - -static int -dmnsn_ld_yylex(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - return dmnsn_yylex(lvalp, llocp, filename, symtable, yyscanner); -} diff --git a/dimension/directives.rules b/dimension/directives.rules deleted file mode 100644 index b9c6cc6..0000000 --- a/dimension/directives.rules +++ /dev/null @@ -1,180 +0,0 @@ -#line 2 "directives.rules" - -/* - * Start symbol - */ - -LANGUAGE_DIRECTIVE: "#include" STRING { - dmnsn_declare_symbol(symtable, "$include", $2); - dmnsn_delete_astnode($2); - } - | "#declare" IDENTIFIER "=" RVALUE { - dmnsn_declare_symbol(symtable, $2.ptr, $4); - dmnsn_delete_astnode($2); - dmnsn_delete_astnode($4); - } - | "#local" IDENTIFIER "=" RVALUE { - dmnsn_local_symbol(symtable, $2.ptr, $4); - dmnsn_delete_astnode($2); - dmnsn_delete_astnode($4); - } - | "#undef" IDENTIFIER { - dmnsn_undef_symbol(symtable, $2.ptr); - dmnsn_delete_astnode($2); - } - | "#if" "(" CONDITIONAL ")" { - dmnsn_astnode cond = dmnsn_eval($3, symtable); - dmnsn_delete_astnode($3); - - if (cond.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode(cond); - YYERROR; - } - - dmnsn_local_symbol(symtable, "$cond", cond); - dmnsn_delete_astnode(cond); - } - | "#ifdef" "(" IDENTIFIER ")" { - dmnsn_astnode *node = dmnsn_find_symbol(symtable, $3.ptr); - dmnsn_local_symbol(symtable, "$cond", - dmnsn_new_ast_integer(node ? 1 : 0)); - dmnsn_delete_astnode($3); - } - | "#ifndef" "(" IDENTIFIER ")" { - dmnsn_astnode *node = dmnsn_find_symbol(symtable, $3.ptr); - dmnsn_local_symbol(symtable, "$cond", - dmnsn_new_ast_integer(node ? 0 : 1)); - dmnsn_delete_astnode($3); - } - | "#version" FLOAT ";" { - dmnsn_diagnostic(@$, "WARNING: POV-Ray #version backwards-" - "compatibility not supported"); - dmnsn_delete_astnode($2); - } - | "#debug" STRING { - fprintf(stderr, "%s\n", (const char *)$2.ptr); - dmnsn_delete_astnode($2); - } - | "#warning" STRING { - dmnsn_diagnostic(@$, "WARNING: %s", (const char *)$2.ptr); - dmnsn_delete_astnode($2); - } - | "#error" STRING { - dmnsn_diagnostic(@$, "%s", (const char *)$2.ptr); - dmnsn_delete_astnode($2); - YYERROR; - } - | "#macro" IDENTIFIER "(" DECL_PARAMS ")" { - dmnsn_declare_symbol(symtable, $2.ptr, $4); - dmnsn_local_symbol(symtable, "$macro", - dmnsn_new_ast_string($2.ptr)); - dmnsn_delete_astnode($2); - dmnsn_delete_astnode($4); - } - | IDENTIFIER "(" PARAMS ")" { - dmnsn_astnode *node = dmnsn_find_symbol(symtable, $1.ptr); - dmnsn_assert(node && node->type == DMNSN_AST_MACRO, - "Attempt to expand non-macro."); - dmnsn_delete_astnode($1); - - size_t nparams = dmnsn_array_size(node->children); - size_t nparams_given = dmnsn_array_size($3.children); - - if (nparams_given != nparams) { - dmnsn_diagnostic(@$, "wrong number of macro arguments" - " (%zu; should be %zu)", - nparams_given, nparams); - dmnsn_delete_astnode($3); - YYERROR; - } - - for (size_t i = 0; i < nparams; ++i) { - dmnsn_astnode id, param; - dmnsn_array_get(node->children, i, &id); - dmnsn_array_get($3.children, i, ¶m); - dmnsn_local_symbol(symtable, id.ptr, param); - } - - dmnsn_delete_astnode($3); - } -; - -RVALUE: ARITH_EXPR ";" %dprec 2 { - $$ = dmnsn_eval($1, symtable); - dmnsn_delete_astnode($1); - - if ($$.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode($$); - YYERROR; - } - } - | COLOR ";" %dprec 1 - | OBJECT - | TEXTURE - | PIGMENT - | FINISH - | INTERIOR - | CAMERA - | "transform" "{" - TRANSFORMATION_ITEMS - "}" - { - $$ = $3; - } -; - -DECL_PARAMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_MACRO, @$); - } - | DECL_PARAM_LIST -; - -DECL_PARAM_LIST: IDENTIFIER { - $$ = dmnsn_new_astnode1(DMNSN_AST_MACRO, @$, $1); - } - | DECL_PARAM_LIST "," IDENTIFIER { - $$ = $1; - dmnsn_array_push($$.children, &$3); - } -; - -PARAMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_ARRAY, @$); - } - | PARAM_LIST -; - -PARAM_LIST: IDENTIFIER %dprec 2 { - $$ = dmnsn_new_astnode1(DMNSN_AST_MACRO, @$, $1); - } - | PARAM %dprec 1 { - $$ = dmnsn_new_astnode1(DMNSN_AST_MACRO, @$, $1); - } - | PARAM_LIST "," IDENTIFIER %dprec 2 { - $$ = $1; - dmnsn_array_push($$.children, &$3); - } - | PARAM_LIST "," PARAM %dprec 1 { - $$ = $1; - dmnsn_array_push($$.children, &$3); - } -; - -PARAM: ARITH_EXPR %dprec 2 { - $$ = dmnsn_eval($1, symtable); - dmnsn_delete_astnode($1); - - if ($$.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode($$); - YYERROR; - } - } - | COLOR %dprec 1 - | OBJECT - | TEXTURE - | PIGMENT - | FINISH - | INTERIOR - | CAMERA - | TRANSFORMATION -; diff --git a/dimension/grammar.declarations b/dimension/grammar.declarations deleted file mode 100644 index a74bcaf..0000000 --- a/dimension/grammar.declarations +++ /dev/null @@ -1,31 +0,0 @@ -#line 2 "grammar.declarations" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -%token-table - -%name-prefix "dmnsn_yy" - -%expect 16 - -%parse-param {const char *filename} -%parse-param {void *yyscanner} -%parse-param {dmnsn_astree *astree} -%parse-param {dmnsn_symbol_table *symtable} diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue deleted file mode 100644 index 9b2fa29..0000000 --- a/dimension/grammar.epilogue +++ /dev/null @@ -1,284 +0,0 @@ -#line 2 "grammar.epilogue" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -dmnsn_astree * -dmnsn_parse(FILE *file, dmnsn_symbol_table *symtable) -{ - const char *filename; - dmnsn_astnode *fnode = dmnsn_find_symbol(symtable, "$file"); - if (fnode && fnode->type == DMNSN_AST_STRING) { - filename = fnode->ptr; - } else { - filename = "<>"; - dmnsn_declare_symbol(symtable, "$file", dmnsn_new_ast_string(filename)); - } - - void *scanner; - dmnsn_astree *astree = dmnsn_new_array(sizeof(dmnsn_astnode)); - - dmnsn_yylex_init(&scanner); - dmnsn_yyset_in(file, scanner); - dmnsn_yyset_extra(NULL, scanner); - - if (yyparse(filename, scanner, astree, symtable) != 0) { - dmnsn_delete_astree(astree); - astree = NULL; - } - - dmnsn_yylex_cleanup(scanner); - dmnsn_yylex_destroy(scanner); - return astree; -} - -dmnsn_astree * -dmnsn_parse_string(const char *str, dmnsn_symbol_table *symtable) -{ - const char *filename; - dmnsn_astnode *fnode = dmnsn_find_symbol(symtable, "$file"); - if (fnode && fnode->type == DMNSN_AST_STRING) { - filename = fnode->ptr; - } else { - filename = "<string>"; - dmnsn_declare_symbol(symtable, "$file", dmnsn_new_ast_string(filename)); - } - - void *scanner; - dmnsn_astree *astree = dmnsn_new_array(sizeof(dmnsn_astnode)); - - dmnsn_yylex_init(&scanner); - dmnsn_yyset_extra(NULL, scanner); - - void *buffer = dmnsn_yy_make_string_buffer(str, scanner); - dmnsn_yy_push_buffer(buffer, scanner); - - if (yyparse(filename, scanner, astree, symtable) != 0) { - dmnsn_delete_astree(astree); - astree = NULL; - } - - dmnsn_yylex_cleanup(scanner); - dmnsn_yylex_destroy(scanner); - return astree; -} - -const char * -dmnsn_token_string(dmnsn_token_type token_type) -{ -#define TOKEN_SIZE 255 - static char token[TOKEN_SIZE + 1]; - - unsigned int i = YYTRANSLATE(token_type); - if (i > YYNTOKENS) { - fprintf(stderr, "WARNING: unrecognised token %d.\n", (int)token_type); - return "unrecognized-token"; - } - - /* Trim the quotation marks */ - - if (strlen(yytname[i]) - 1 >= TOKEN_SIZE) { - fprintf(stderr, "WARNING: name of token %d too long.\n", (int)token_type); - return "unrepresentable-token"; - } - - strcpy(token, yytname[i] + 1); - token[strlen(token) - 1] = '\0'; - - return token; -#undef TOKEN_SIZE -} - -const char * -dmnsn_astnode_string(dmnsn_astnode_type astnode_type) -{ - switch (astnode_type) { - /* Macro to shorten this switch */ -#define dmnsn_astnode_map(type, str) \ - case type: \ - return str; - - dmnsn_astnode_map(DMNSN_AST_NONE, "none"); - - dmnsn_astnode_map(DMNSN_AST_GLOBAL_SETTINGS, "global_settings"); - dmnsn_astnode_map(DMNSN_AST_ADC_BAILOUT, "adc_bailout"); - dmnsn_astnode_map(DMNSN_AST_ASSUMED_GAMMA, "assumed_gamma"); - dmnsn_astnode_map(DMNSN_AST_CHARSET, "charset"); - dmnsn_astnode_map(DMNSN_AST_ASCII, "ascii"); - dmnsn_astnode_map(DMNSN_AST_UTF8, "utf8"); - dmnsn_astnode_map(DMNSN_AST_SYS, "sys"); - dmnsn_astnode_map(DMNSN_AST_MAX_INTERSECTIONS, "max_intersections"); - dmnsn_astnode_map(DMNSN_AST_MAX_TRACE_LEVEL, "max_trace_level"); - - dmnsn_astnode_map(DMNSN_AST_BACKGROUND, "background"); - dmnsn_astnode_map(DMNSN_AST_SKY_SPHERE, "sky_sphere"); - - dmnsn_astnode_map(DMNSN_AST_CAMERA, "camera"); - dmnsn_astnode_map(DMNSN_AST_PERSPECTIVE, "perspective"); - dmnsn_astnode_map(DMNSN_AST_LOCATION, "location"); - dmnsn_astnode_map(DMNSN_AST_RIGHT, "right"); - dmnsn_astnode_map(DMNSN_AST_UP, "up"); - dmnsn_astnode_map(DMNSN_AST_SKY, "sky"); - dmnsn_astnode_map(DMNSN_AST_ANGLE, "angle"); - dmnsn_astnode_map(DMNSN_AST_LOOK_AT, "look_at"); - dmnsn_astnode_map(DMNSN_AST_DIRECTION, "direction"); - - dmnsn_astnode_map(DMNSN_AST_OBJECT, "object"); - dmnsn_astnode_map(DMNSN_AST_BOX, "box"); - dmnsn_astnode_map(DMNSN_AST_CONE, "cone"); - dmnsn_astnode_map(DMNSN_AST_CYLINDER, "cylinder"); - dmnsn_astnode_map(DMNSN_AST_DIFFERENCE, "difference"); - dmnsn_astnode_map(DMNSN_AST_INTERSECTION, "intersection"); - dmnsn_astnode_map(DMNSN_AST_LIGHT_SOURCE, "light_source"); - dmnsn_astnode_map(DMNSN_AST_MERGE, "merge"); - dmnsn_astnode_map(DMNSN_AST_PLANE, "plane"); - dmnsn_astnode_map(DMNSN_AST_SPHERE, "sphere"); - dmnsn_astnode_map(DMNSN_AST_TORUS, "torus"); - dmnsn_astnode_map(DMNSN_AST_UNION, "union"); - - dmnsn_astnode_map(DMNSN_AST_OBJECT_MODIFIERS, "object-modifiers"); - dmnsn_astnode_map(DMNSN_AST_STURM, "sturm"); - - dmnsn_astnode_map(DMNSN_AST_PATTERN, "pattern"); - dmnsn_astnode_map(DMNSN_AST_CHECKER, "checker"); - dmnsn_astnode_map(DMNSN_AST_GRADIENT, "gradient"); - - dmnsn_astnode_map(DMNSN_AST_TEXTURE, "texture"); - - dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment"); - dmnsn_astnode_map(DMNSN_AST_PIGMENT_MODIFIERS, "pigment-modifiers"); - dmnsn_astnode_map(DMNSN_AST_COLOR_LIST, "color-list"); - dmnsn_astnode_map(DMNSN_AST_COLOR_MAP, "color_map"); - dmnsn_astnode_map(DMNSN_AST_COLOR_MAP_ENTRY, "color_map-entry"); - dmnsn_astnode_map(DMNSN_AST_PIGMENT_LIST, "pigment-list"); - dmnsn_astnode_map(DMNSN_AST_PIGMENT_MAP, "pigment_map"); - dmnsn_astnode_map(DMNSN_AST_PIGMENT_MAP_ENTRY, "pigment_map-entry"); - dmnsn_astnode_map(DMNSN_AST_QUICK_COLOR, "quick_color"); - dmnsn_astnode_map(DMNSN_AST_IMAGE_MAP, "image_map"); - dmnsn_astnode_map(DMNSN_AST_PNG, "png"); - - dmnsn_astnode_map(DMNSN_AST_FINISH, "finish"); - dmnsn_astnode_map(DMNSN_AST_AMBIENT, "ambient"); - dmnsn_astnode_map(DMNSN_AST_DIFFUSE, "diffuse"); - dmnsn_astnode_map(DMNSN_AST_PHONG, "phong"); - dmnsn_astnode_map(DMNSN_AST_PHONG_SIZE, "phong_size"); - - dmnsn_astnode_map(DMNSN_AST_REFLECTION, "reflection"); - dmnsn_astnode_map(DMNSN_AST_REFLECTION_ITEMS, "reflection-items"); - dmnsn_astnode_map(DMNSN_AST_FALLOFF, "falloff"); - - dmnsn_astnode_map(DMNSN_AST_INTERIOR, "interior"); - dmnsn_astnode_map(DMNSN_AST_IOR, "ior"); - - dmnsn_astnode_map(DMNSN_AST_TRANSFORMATION, "transformation"); - dmnsn_astnode_map(DMNSN_AST_ROTATION, "rotation"); - dmnsn_astnode_map(DMNSN_AST_SCALE, "scale"); - dmnsn_astnode_map(DMNSN_AST_TRANSLATION, "translation"); - dmnsn_astnode_map(DMNSN_AST_MATRIX, "matrix"); - dmnsn_astnode_map(DMNSN_AST_INVERSE, "inverse"); - - dmnsn_astnode_map(DMNSN_AST_FLOAT, "float"); - dmnsn_astnode_map(DMNSN_AST_INTEGER, "integer"); - - dmnsn_astnode_map(DMNSN_AST_VECTOR, "vector"); - - dmnsn_astnode_map(DMNSN_AST_ADD, "+"); - dmnsn_astnode_map(DMNSN_AST_SUB, "-"); - dmnsn_astnode_map(DMNSN_AST_MUL, "*"); - dmnsn_astnode_map(DMNSN_AST_DIV, "/"); - - dmnsn_astnode_map(DMNSN_AST_EQUAL, "=" ); - dmnsn_astnode_map(DMNSN_AST_NOT_EQUAL, "!="); - dmnsn_astnode_map(DMNSN_AST_LESS, "<" ); - dmnsn_astnode_map(DMNSN_AST_LESS_EQUAL, "<="); - dmnsn_astnode_map(DMNSN_AST_GREATER, ">" ); - dmnsn_astnode_map(DMNSN_AST_GREATER_EQUAL, ">="); - dmnsn_astnode_map(DMNSN_AST_AND, "&" ); - dmnsn_astnode_map(DMNSN_AST_OR, "|" ); - dmnsn_astnode_map(DMNSN_AST_NOT, "!" ); - dmnsn_astnode_map(DMNSN_AST_TERNARY, "?:"); - - dmnsn_astnode_map(DMNSN_AST_ABS, "abs"); - dmnsn_astnode_map(DMNSN_AST_ACOS, "acos"); - dmnsn_astnode_map(DMNSN_AST_ACOSH, "acosh"); - dmnsn_astnode_map(DMNSN_AST_ASC, "asc"); - dmnsn_astnode_map(DMNSN_AST_ASIN, "asin"); - dmnsn_astnode_map(DMNSN_AST_ASINH, "asinh"); - dmnsn_astnode_map(DMNSN_AST_ATAN, "atan"); - dmnsn_astnode_map(DMNSN_AST_ATAN2, "atan2"); - dmnsn_astnode_map(DMNSN_AST_ATANH, "atanh"); - dmnsn_astnode_map(DMNSN_AST_CEIL, "ceil"); - dmnsn_astnode_map(DMNSN_AST_COS, "cos"); - dmnsn_astnode_map(DMNSN_AST_COSH, "cosh"); - dmnsn_astnode_map(DMNSN_AST_DEGREES, "degrees"); - dmnsn_astnode_map(DMNSN_AST_INT_DIV, "div"); - dmnsn_astnode_map(DMNSN_AST_EXP, "exp"); - dmnsn_astnode_map(DMNSN_AST_FLOOR, "floor"); - dmnsn_astnode_map(DMNSN_AST_INT, "int"); - dmnsn_astnode_map(DMNSN_AST_LN, "ln"); - dmnsn_astnode_map(DMNSN_AST_LOG, "log"); - dmnsn_astnode_map(DMNSN_AST_MAX, "max"); - dmnsn_astnode_map(DMNSN_AST_MIN, "min"); - dmnsn_astnode_map(DMNSN_AST_MOD, "mod"); - dmnsn_astnode_map(DMNSN_AST_POW, "pow"); - dmnsn_astnode_map(DMNSN_AST_RADIANS, "radians"); - dmnsn_astnode_map(DMNSN_AST_SIN, "sin"); - dmnsn_astnode_map(DMNSN_AST_SINH, "sinh"); - dmnsn_astnode_map(DMNSN_AST_SQRT, "sqrt"); - dmnsn_astnode_map(DMNSN_AST_STRCMP, "strcmp"); - dmnsn_astnode_map(DMNSN_AST_STRLEN, "strlen"); - dmnsn_astnode_map(DMNSN_AST_TAN, "tan"); - dmnsn_astnode_map(DMNSN_AST_TANH, "tanh"); - dmnsn_astnode_map(DMNSN_AST_VAL, "val"); - dmnsn_astnode_map(DMNSN_AST_VAXIS_ROTATE, "vaxis_rotate"); - dmnsn_astnode_map(DMNSN_AST_VCROSS, "vcross"); - dmnsn_astnode_map(DMNSN_AST_VDOT, "vdot"); - dmnsn_astnode_map(DMNSN_AST_VLENGTH, "vlength"); - dmnsn_astnode_map(DMNSN_AST_VNORMALIZE, "vnormalize"); - dmnsn_astnode_map(DMNSN_AST_VROTATE, "vrotate"); - - dmnsn_astnode_map(DMNSN_AST_PI, "pi"); - dmnsn_astnode_map(DMNSN_AST_TRUE, "true"); - dmnsn_astnode_map(DMNSN_AST_FALSE, "false"); - dmnsn_astnode_map(DMNSN_AST_X, "x"); - dmnsn_astnode_map(DMNSN_AST_Y, "y"); - dmnsn_astnode_map(DMNSN_AST_Z, "z"); - dmnsn_astnode_map(DMNSN_AST_T, "t"); - - dmnsn_astnode_map(DMNSN_AST_NEGATE, "-"); - dmnsn_astnode_map(DMNSN_AST_DOT_X, ".x"); - dmnsn_astnode_map(DMNSN_AST_DOT_Y, ".y"); - dmnsn_astnode_map(DMNSN_AST_DOT_Z, ".z"); - dmnsn_astnode_map(DMNSN_AST_DOT_T, ".t"); - dmnsn_astnode_map(DMNSN_AST_DOT_TRANSMIT, ".transmit"); - - dmnsn_astnode_map(DMNSN_AST_IDENTIFIER, "identifier"); - - dmnsn_astnode_map(DMNSN_AST_STRING, "string"); - - dmnsn_astnode_map(DMNSN_AST_ARRAY, "array"); - - dmnsn_astnode_map(DMNSN_AST_MACRO, "macro"); - - default: - fprintf(stderr, "WARNING: unrecognised astnode type %d.\n", - (int)astnode_type); - return "unrecognized-astnode"; - } -} diff --git a/dimension/grammar.nonterminals b/dimension/grammar.nonterminals deleted file mode 100644 index 8135c44..0000000 --- a/dimension/grammar.nonterminals +++ /dev/null @@ -1,35 +0,0 @@ -#line 2 "grammar.nonterminals" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -/* Top-level items */ -%type <astnode> SCENE_ITEM - -/* Global settings */ -%type <astnode> GLOBAL_SETTINGS -%type <astnode> GLOBAL_SETTINGS_ITEMS -%type <astnode> GLOBAL_SETTINGS_ITEM -%type <astnode> GLOBAL_CHARSET - -/* Atmospheric effects */ -%type <astnode> ATMOSPHERIC_EFFECT -%type <astnode> BACKGROUND -%type <astnode> SKY_SPHERE -%type <astnode> SKY_SPHERE_ITEMS diff --git a/dimension/grammar.prologue b/dimension/grammar.prologue deleted file mode 100644 index d335d2b..0000000 --- a/dimension/grammar.prologue +++ /dev/null @@ -1,27 +0,0 @@ -#line 2 "grammar.prologue" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -void -yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, - dmnsn_astree *astree, dmnsn_symbol_table *symtable, const char *str) -{ - dmnsn_diagnostic(*locp, "%s", str); -} diff --git a/dimension/grammar.rules b/dimension/grammar.rules deleted file mode 100644 index 148e082..0000000 --- a/dimension/grammar.rules +++ /dev/null @@ -1,127 +0,0 @@ -#line 2 "grammar.rules" - -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -/* - * Start symbol - */ - -SCENE: /* empty */ - | SCENE SCENE_ITEM { - dmnsn_array_push(astree, &$2); - } -; - -/* Top-level scene item */ -SCENE_ITEM: GLOBAL_SETTINGS - | ATMOSPHERIC_EFFECT - | CAMERA - | OBJECT -; - -/* Global settings */ - -GLOBAL_SETTINGS: "global_settings" "{" - GLOBAL_SETTINGS_ITEMS - "}" - { - $$ = $3; - } -; - -GLOBAL_SETTINGS_ITEMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_GLOBAL_SETTINGS, @$); - } - | GLOBAL_SETTINGS_ITEMS GLOBAL_SETTINGS_ITEM { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; - -GLOBAL_SETTINGS_ITEM: "adc_bailout" FLOAT { - $$ = dmnsn_new_astnode1(DMNSN_AST_ADC_BAILOUT, @$, $2); - } - | "ambient_light" COLOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_AMBIENT, @$, $2); - } - | "assumed_gamma" FLOAT { - dmnsn_diagnostic(@1, - "WARNING: assumed_gamma not supported"); - $$ = dmnsn_new_astnode1(DMNSN_AST_ASSUMED_GAMMA, @$, $2); - } - | "charset" GLOBAL_CHARSET { - dmnsn_diagnostic(@1, - "WARNING: charset not supported"); - $$ = dmnsn_new_astnode1(DMNSN_AST_CHARSET, @$, $2); - } - | "max_intersections" INT { - dmnsn_diagnostic(@1, - "WARNING: max_intersections is" - " unnecessary for Dimension"); - $$ = dmnsn_new_astnode1(DMNSN_AST_MAX_INTERSECTIONS, @$, - $2); - } - | "max_trace_level" INT { - $$ = dmnsn_new_astnode1(DMNSN_AST_MAX_TRACE_LEVEL, @$, - $2); - } -; - -GLOBAL_CHARSET: "ascii" { - $$ = dmnsn_new_astleaf(DMNSN_AST_ASCII, @$); - } - | "utf8" { - $$ = dmnsn_new_astleaf(DMNSN_AST_UTF8, @$); - } - | "sys" { - $$ = dmnsn_new_astleaf(DMNSN_AST_SYS, @$); - } - -/* Atmospheric effects */ - -ATMOSPHERIC_EFFECT: BACKGROUND - | SKY_SPHERE -; - -BACKGROUND: "background" "{" COLOR "}" { - $$ = dmnsn_new_astnode1(DMNSN_AST_BACKGROUND, @$, $3); - } -; - -SKY_SPHERE: "sky_sphere" "{" - SKY_SPHERE_ITEMS - "}" - { - $$ = $3; - } -; - -SKY_SPHERE_ITEMS: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_SKY_SPHERE, @$); - } - | SKY_SPHERE_ITEMS PIGMENT { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } - | SKY_SPHERE_ITEMS TRANSFORMATION { - $$ = $1; - dmnsn_array_push($$.children, &$2); - } -; diff --git a/dimension/lexer.l b/dimension/lexer.l deleted file mode 100644 index 89cc0a7..0000000 --- a/dimension/lexer.l +++ /dev/null @@ -1,494 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -%option reentrant -%option stack -%option yylineno -%option noyywrap -%option never-interactive -%option prefix="dmnsn_yy" -%option outfile="lex.yy.c" - -%{ -#include "parse.h" -#include "tokenize.h" -#include "utility.h" -#include <stdlib.h> -#include <stdio.h> - -#define YY_DECL int dmnsn_yylex_impl(dmnsn_parse_item *lvalp, \ - dmnsn_parse_location *llocp, \ - const char *filename, \ - yyscan_t yyscanner) -%} - -%x DMNSN_BLOCK_COMMENT -%x DMNSN_LINE_COMMENT -%x DMNSN_STRING -%x DMNSN_STRING_ESCAPE - -%% - -%{ -/* Some helpful macros that set fields of a token correctly, and other stuff */ - -#define NEW_TOKEN(token_type) \ - do { \ - token = token_type; \ - lvalp->value = NULL; \ - llocp->first_filename = llocp->last_filename = filename; \ - llocp->first_line = llocp->last_line = yylineno; \ - llocp->first_column = yycolumn; \ - llocp->last_column = yycolumn + yyleng; \ - llocp->parent = NULL; \ - } while (0) - -#define CALCULATE_COLUMN() do { yycolumn += yyleng; } while (0) - -#define RETURN() \ - do { \ - CALCULATE_COLUMN(); \ - return token; \ - } while (0) - -#define RETURN_TOKEN(token_type) \ - do { \ - NEW_TOKEN(token_type); \ - RETURN(); \ - } while (0) - -#define RETURN_VALUE_TOKEN(token_type) \ - do { \ - NEW_TOKEN(token_type); \ - lvalp->value = dmnsn_strdup(yytext); \ - RETURN(); \ - } while (0) - -#define STRING_TOKEN() \ - do { \ - NEW_TOKEN(DMNSN_T_STRING); \ - lvalp->value = dmnsn_malloc(string_extent); \ - lvalp->value[0] = '\0'; \ - CALCULATE_COLUMN(); \ - } while (0) - -#define STRCAT(str, len) \ - do { \ - if (string_length + len + 1 >= string_length) { \ - string_extent = 2*(string_length + len + 1); \ - lvalp->value = dmnsn_realloc(lvalp->value, string_extent); \ - } \ - \ - strncpy(lvalp->value + string_length, str, len + 1); \ - string_length += len; \ - CALCULATE_COLUMN(); \ - } while(0) - -int token = DMNSN_T_LEX_ERROR; -size_t string_length = 0, string_extent = 8; -unsigned int wchar; - -/* Silence some warnings */ -(void)yyunput; -(void)input; -(void)yy_top_state; -%} - -(?# Comments) - -<INITIAL,DMNSN_BLOCK_COMMENT>"/*" { - yy_push_state(DMNSN_BLOCK_COMMENT, yyscanner); - CALCULATE_COLUMN(); -} -<DMNSN_BLOCK_COMMENT>"*/" CALCULATE_COLUMN(); yy_pop_state(yyscanner); -<DMNSN_BLOCK_COMMENT>[^*/\n]* CALCULATE_COLUMN(); -<DMNSN_BLOCK_COMMENT>"/" CALCULATE_COLUMN(); -<DMNSN_BLOCK_COMMENT>"*" CALCULATE_COLUMN(); -<DMNSN_BLOCK_COMMENT>\n ; - -"//" { - yy_push_state(DMNSN_LINE_COMMENT, yyscanner); - CALCULATE_COLUMN(); -} -<DMNSN_LINE_COMMENT>\n ; yy_pop_state(yyscanner); -<DMNSN_LINE_COMMENT>[^\n]+ CALCULATE_COLUMN(); - -(?# Punctuation) -"{" RETURN_TOKEN(DMNSN_T_LBRACE); -"}" RETURN_TOKEN(DMNSN_T_RBRACE); -"(" RETURN_TOKEN(DMNSN_T_LPAREN); -")" RETURN_TOKEN(DMNSN_T_RPAREN); -"[" RETURN_TOKEN(DMNSN_T_LBRACKET); -"]" RETURN_TOKEN(DMNSN_T_RBRACKET); -"+" RETURN_TOKEN(DMNSN_T_PLUS); -"-" RETURN_TOKEN(DMNSN_T_MINUS); -"*" RETURN_TOKEN(DMNSN_T_STAR); -"/" RETURN_TOKEN(DMNSN_T_SLASH); -"," RETURN_TOKEN(DMNSN_T_COMMA); -";" RETURN_TOKEN(DMNSN_T_SEMICOLON); -"?" RETURN_TOKEN(DMNSN_T_QUESTION); -":" RETURN_TOKEN(DMNSN_T_COLON); -"&" RETURN_TOKEN(DMNSN_T_AND); -"." RETURN_TOKEN(DMNSN_T_DOT); -"|" RETURN_TOKEN(DMNSN_T_PIPE); -"<" RETURN_TOKEN(DMNSN_T_LESS); -">" RETURN_TOKEN(DMNSN_T_GREATER); -"!" RETURN_TOKEN(DMNSN_T_BANG); -"=" RETURN_TOKEN(DMNSN_T_EQUALS); -"<=" RETURN_TOKEN(DMNSN_T_LESS_EQUAL); -">=" RETURN_TOKEN(DMNSN_T_GREATER_EQUAL); -"!=" RETURN_TOKEN(DMNSN_T_NOT_EQUAL); - -(?# Integers) -[[:digit:]]+ | -0(x|X)[[:digit:]aAbBcCdDeEfF]+ RETURN_VALUE_TOKEN(DMNSN_T_INTEGER); - -(?# Floats) -[[:digit:]]*\.?[[:digit:]]+((e|E)(\+|-)?[[:digit:]]+)? { - RETURN_VALUE_TOKEN(DMNSN_T_FLOAT); -} - -(?# Keywords) -"abs" RETURN_TOKEN(DMNSN_T_ABS); -"acos" RETURN_TOKEN(DMNSN_T_ACOS); -"acosh" RETURN_TOKEN(DMNSN_T_ACOSH); -"adc_bailout" RETURN_TOKEN(DMNSN_T_ADC_BAILOUT); -"ambient" RETURN_TOKEN(DMNSN_T_AMBIENT); -"ambient_light" RETURN_TOKEN(DMNSN_T_AMBIENT_LIGHT); -"angle" RETURN_TOKEN(DMNSN_T_ANGLE); -"asc" RETURN_TOKEN(DMNSN_T_ASC); -"ascii" RETURN_TOKEN(DMNSN_T_ASCII); -"asin" RETURN_TOKEN(DMNSN_T_ASIN); -"asinh" RETURN_TOKEN(DMNSN_T_ASINH); -"assumed_gamma" RETURN_TOKEN(DMNSN_T_ASSUMED_GAMMA); -"atan" RETURN_TOKEN(DMNSN_T_ATAN); -"atan2" RETURN_TOKEN(DMNSN_T_ATAN2); -"atanh" RETURN_TOKEN(DMNSN_T_ATANH); -"background" RETURN_TOKEN(DMNSN_T_BACKGROUND); -"box" RETURN_TOKEN(DMNSN_T_BOX); -"blue" RETURN_TOKEN(DMNSN_T_BLUE); -"ceil" RETURN_TOKEN(DMNSN_T_CEIL); -"camera" RETURN_TOKEN(DMNSN_T_CAMERA); -"charset" RETURN_TOKEN(DMNSN_T_CHARSET); -"checker" RETURN_TOKEN(DMNSN_T_CHECKER); -"color" RETURN_TOKEN(DMNSN_T_COLOR); -"color_map" RETURN_TOKEN(DMNSN_T_COLOR_MAP); -"colour" RETURN_TOKEN(DMNSN_T_COLOR); -"colour_map" RETURN_TOKEN(DMNSN_T_COLOR_MAP); -"cone" RETURN_TOKEN(DMNSN_T_CONE); -"cos" RETURN_TOKEN(DMNSN_T_COS); -"cosh" RETURN_TOKEN(DMNSN_T_COSH); -"cylinder" RETURN_TOKEN(DMNSN_T_CYLINDER); -"degrees" RETURN_TOKEN(DMNSN_T_DEGREES); -"difference" RETURN_TOKEN(DMNSN_T_DIFFERENCE); -"diffuse" RETURN_TOKEN(DMNSN_T_DIFFUSE); -"direction" RETURN_TOKEN(DMNSN_T_DIRECTION); -"div" RETURN_TOKEN(DMNSN_T_DIV); -"exp" RETURN_TOKEN(DMNSN_T_EXP); -"falloff" RETURN_TOKEN(DMNSN_T_FALLOFF); -"false" RETURN_TOKEN(DMNSN_T_FALSE); -"filter" RETURN_TOKEN(DMNSN_T_FILTER); -"finish" RETURN_TOKEN(DMNSN_T_FINISH); -"floor" RETURN_TOKEN(DMNSN_T_FLOOR); -"global_settings" RETURN_TOKEN(DMNSN_T_GLOBAL_SETTINGS); -"gradient" RETURN_TOKEN(DMNSN_T_GRADIENT); -"gray" RETURN_TOKEN(DMNSN_T_GRAY); -"grey" RETURN_TOKEN(DMNSN_T_GRAY); -"green" RETURN_TOKEN(DMNSN_T_GREEN); -"image_height" RETURN_TOKEN(DMNSN_T_IMAGE_HEIGHT); -"image_map" RETURN_TOKEN(DMNSN_T_IMAGE_MAP); -"image_width" RETURN_TOKEN(DMNSN_T_IMAGE_WIDTH); -"int" RETURN_TOKEN(DMNSN_T_INT); -"interior" RETURN_TOKEN(DMNSN_T_INTERIOR); -"intersection" RETURN_TOKEN(DMNSN_T_INTERSECTION); -"inverse" RETURN_TOKEN(DMNSN_T_INVERSE); -"ior" RETURN_TOKEN(DMNSN_T_IOR); -"ln" RETURN_TOKEN(DMNSN_T_LN); -"location" RETURN_TOKEN(DMNSN_T_LOCATION); -"log" RETURN_TOKEN(DMNSN_T_LOG); -"look_at" RETURN_TOKEN(DMNSN_T_LOOK_AT); -"light_source" RETURN_TOKEN(DMNSN_T_LIGHT_SOURCE); -"matrix" RETURN_TOKEN(DMNSN_T_MATRIX); -"max" RETURN_TOKEN(DMNSN_T_MAX); -"max_intersections" RETURN_TOKEN(DMNSN_T_MAX_INTERSECTIONS); -"max_trace_level" RETURN_TOKEN(DMNSN_T_MAX_TRACE_LEVEL); -"merge" RETURN_TOKEN(DMNSN_T_MERGE); -"min" RETURN_TOKEN(DMNSN_T_MIN); -"mod" RETURN_TOKEN(DMNSN_T_MOD); -"no" RETURN_TOKEN(DMNSN_T_NO); -"object" RETURN_TOKEN(DMNSN_T_OBJECT); -"off" RETURN_TOKEN(DMNSN_T_OFF); -"on" RETURN_TOKEN(DMNSN_T_ON); -"open" RETURN_TOKEN(DMNSN_T_OPEN); -"perspective" RETURN_TOKEN(DMNSN_T_PERSPECTIVE); -"phong" RETURN_TOKEN(DMNSN_T_PHONG); -"phong_size" RETURN_TOKEN(DMNSN_T_PHONG_SIZE); -"pi" RETURN_TOKEN(DMNSN_T_PI); -"pigment" RETURN_TOKEN(DMNSN_T_PIGMENT); -"pigment_map" RETURN_TOKEN(DMNSN_T_PIGMENT_MAP); -"plane" RETURN_TOKEN(DMNSN_T_PLANE); -"png" RETURN_TOKEN(DMNSN_T_PNG); -"pow" RETURN_TOKEN(DMNSN_T_POW); -"quick_color" RETURN_TOKEN(DMNSN_T_QUICK_COLOR); -"quick_colour" RETURN_TOKEN(DMNSN_T_QUICK_COLOR); -"radians" RETURN_TOKEN(DMNSN_T_RADIANS); -"red" RETURN_TOKEN(DMNSN_T_RED); -"reflection" RETURN_TOKEN(DMNSN_T_REFLECTION); -"rgb" RETURN_TOKEN(DMNSN_T_RGB); -"rgbf" RETURN_TOKEN(DMNSN_T_RGBF); -"rgbft" RETURN_TOKEN(DMNSN_T_RGBFT); -"rgbt" RETURN_TOKEN(DMNSN_T_RGBT); -"right" RETURN_TOKEN(DMNSN_T_RIGHT); -"rotate" RETURN_TOKEN(DMNSN_T_ROTATE); -"scale" RETURN_TOKEN(DMNSN_T_SCALE); -"sin" RETURN_TOKEN(DMNSN_T_SIN); -"sinh" RETURN_TOKEN(DMNSN_T_SINH); -"sky" RETURN_TOKEN(DMNSN_T_SKY); -"sky_sphere" RETURN_TOKEN(DMNSN_T_SKY_SPHERE); -"sphere" RETURN_TOKEN(DMNSN_T_SPHERE); -"sqrt" RETURN_TOKEN(DMNSN_T_SQRT); -"strcmp" RETURN_TOKEN(DMNSN_T_STRCMP); -"strlen" RETURN_TOKEN(DMNSN_T_STRLEN); -"sturm" RETURN_TOKEN(DMNSN_T_STURM); -"sys" RETURN_TOKEN(DMNSN_T_SYS); -"t" RETURN_TOKEN(DMNSN_T_T); -"tan" RETURN_TOKEN(DMNSN_T_TAN); -"tanh" RETURN_TOKEN(DMNSN_T_TANH); -"texture" RETURN_TOKEN(DMNSN_T_TEXTURE); -"torus" RETURN_TOKEN(DMNSN_T_TORUS); -"transform" RETURN_TOKEN(DMNSN_T_TRANSFORM); -"translate" RETURN_TOKEN(DMNSN_T_TRANSLATE); -"transmit" RETURN_TOKEN(DMNSN_T_TRANSMIT); -"true" RETURN_TOKEN(DMNSN_T_TRUE); -"u" RETURN_TOKEN(DMNSN_T_U); -"union" RETURN_TOKEN(DMNSN_T_UNION); -"up" RETURN_TOKEN(DMNSN_T_UP); -"utf8" RETURN_TOKEN(DMNSN_T_UTF8); -"v" RETURN_TOKEN(DMNSN_T_V); -"val" RETURN_TOKEN(DMNSN_T_VAL); -"vaxis_rotate" RETURN_TOKEN(DMNSN_T_VAXIS_ROTATE); -"vcross" RETURN_TOKEN(DMNSN_T_VCROSS); -"vdot" RETURN_TOKEN(DMNSN_T_VDOT); -"vlength" RETURN_TOKEN(DMNSN_T_VLENGTH); -"vrotate" RETURN_TOKEN(DMNSN_T_VROTATE); -"vnormalize" RETURN_TOKEN(DMNSN_T_VNORMALIZE); -"x" RETURN_TOKEN(DMNSN_T_X); -"y" RETURN_TOKEN(DMNSN_T_Y); -"yes" RETURN_TOKEN(DMNSN_T_YES); -"z" RETURN_TOKEN(DMNSN_T_Z); - -(?# Directives) -#[\b\r\t\v ]*break RETURN_TOKEN(DMNSN_T_BREAK); -#[\b\r\t\v ]*case RETURN_TOKEN(DMNSN_T_CASE); -#[\b\r\t\v ]*debug RETURN_TOKEN(DMNSN_T_DEBUG); -#[\b\r\t\v ]*declare RETURN_TOKEN(DMNSN_T_DECLARE); -#[\b\r\t\v ]*default RETURN_TOKEN(DMNSN_T_DEFAULT); -#[\b\r\t\v ]*else RETURN_TOKEN(DMNSN_T_ELSE); -#[\b\r\t\v ]*end RETURN_TOKEN(DMNSN_T_END); -#[\b\r\t\v ]*error RETURN_TOKEN(DMNSN_T_ERROR); -#[\b\r\t\v ]*fclose RETURN_TOKEN(DMNSN_T_FCLOSE); -#[\b\r\t\v ]*fopen RETURN_TOKEN(DMNSN_T_FOPEN); -#[\b\r\t\v ]*if RETURN_TOKEN(DMNSN_T_IF); -#[\b\r\t\v ]*ifdef RETURN_TOKEN(DMNSN_T_IFDEF); -#[\b\r\t\v ]*ifndef RETURN_TOKEN(DMNSN_T_IFNDEF); -#[\b\r\t\v ]*include RETURN_TOKEN(DMNSN_T_INCLUDE); -#[\b\r\t\v ]*local RETURN_TOKEN(DMNSN_T_LOCAL); -#[\b\r\t\v ]*macro RETURN_TOKEN(DMNSN_T_MACRO); -#[\b\r\t\v ]*range RETURN_TOKEN(DMNSN_T_RANGE); -#[\b\r\t\v ]*read RETURN_TOKEN(DMNSN_T_READ); -#[\b\r\t\v ]*render RETURN_TOKEN(DMNSN_T_RENDER); -#[\b\r\t\v ]*statistics RETURN_TOKEN(DMNSN_T_STATISTICS); -#[\b\r\t\v ]*switch RETURN_TOKEN(DMNSN_T_SWITCH); -#[\b\r\t\v ]*undef RETURN_TOKEN(DMNSN_T_UNDEF); -#[\b\r\t\v ]*version RETURN_TOKEN(DMNSN_T_VERSION); -#[\b\r\t\v ]*warning RETURN_TOKEN(DMNSN_T_WARNING); -#[\b\r\t\v ]*while RETURN_TOKEN(DMNSN_T_WHILE); -#[\b\r\t\v ]*write RETURN_TOKEN(DMNSN_T_WRITE); -#[\b\r\t\v ]*[[:alnum:]_]* { - NEW_TOKEN(DMNSN_T_LEX_ERROR); - dmnsn_diagnostic(*llocp, "unrecognized language directive '%s'", yytext); - RETURN(); -} - -(?# Identifiers) -[[:alpha:]_][[:alnum:]_]* RETURN_VALUE_TOKEN(DMNSN_T_IDENTIFIER); - -(?# Strings) - -"\"" STRING_TOKEN(); yy_push_state(DMNSN_STRING, yyscanner); -<DMNSN_STRING>[^\\\"\n]* STRCAT(yytext, yyleng); -<DMNSN_STRING>"\"" yy_pop_state(yyscanner); RETURN(); - -(?# String escape sequences) - -<DMNSN_STRING>"\\" { - yy_push_state(DMNSN_STRING_ESCAPE, yyscanner); - CALCULATE_COLUMN(); -} -<DMNSN_STRING_ESCAPE>"a" STRCAT("\a", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"b" STRCAT("\b", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"f" STRCAT("\f", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"n" STRCAT("\n", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"r" STRCAT("\r", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"t" STRCAT("\t", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"v" STRCAT("\v", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"\\" STRCAT("\\", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"'" STRCAT("'", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"\"" STRCAT("\"", 1); yy_pop_state(yyscanner); -<DMNSN_STRING_ESCAPE>"u"[[:digit:]aAbBcCdDeEfF]{4} { - dmnsn_strtoui(&wchar, yytext + 1, 16); - STRCAT("", 2); - lvalp->value[string_length - 2] = wchar/256; - lvalp->value[string_length - 1] = wchar%256; - yy_pop_state(yyscanner); -} -<DMNSN_STRING_ESCAPE>. { - dmnsn_parse_location location; - location.first_filename = location.last_filename = filename; - location.first_line = location.last_line = yylineno; - location.first_column = yycolumn; - location.last_column = yycolumn + yyleng; - dmnsn_diagnostic(location, "WARNING: unrecognised escape sequence '\\%c'", - (int)*yytext); - STRCAT(yytext, yyleng); - yy_pop_state(yyscanner); -} - -(?# Ignore whitespace) -[\b\r\t\v ]+ CALCULATE_COLUMN(); -\n ; - -(?# Fall-through) -. { - NEW_TOKEN(DMNSN_T_LEX_ERROR); - dmnsn_diagnostic(*llocp, "unrecognized character '%c' (0x%X)", - (int)*yytext, (unsigned int)(unsigned char)*yytext); - RETURN(); -} - -%% - -void * -dmnsn_yy_make_buffer(FILE *file, void *scanner) -{ - return dmnsn_yy_create_buffer(file, YY_BUF_SIZE, scanner); -} - -void * -dmnsn_yy_make_string_buffer(const char *str, void *scanner) -{ - return dmnsn_yy_scan_string(str, scanner); -} - -void -dmnsn_yy_push_buffer(void *buffer, void *scanner) -{ - dmnsn_yypush_buffer_state(buffer, scanner); -} - -void -dmnsn_yy_pop_buffer(void *scanner) -{ - dmnsn_yypop_buffer_state(scanner); -} - -dmnsn_array * -dmnsn_tokenize(FILE *file, const char *filename) -{ - dmnsn_token token; - dmnsn_parse_item item; - dmnsn_parse_location location; - dmnsn_array *tokens = dmnsn_new_array(sizeof(dmnsn_token)); - - yyscan_t scanner; - - yylex_init(&scanner); - yyset_in(file, scanner); - yyset_extra(NULL, scanner); - - while ((token.type = dmnsn_yylex_impl(&item, &location, filename, scanner)) - != 0) - { - token.value = item.value; - token.filename = location.first_filename; - token.line = location.first_line; - token.col = location.first_column; - dmnsn_array_push(tokens, &token); - } - - yylex_destroy(scanner); - return tokens; -} - -static void -dmnsn_delete_token(dmnsn_token token) -{ - dmnsn_free(token.value); -} - -void -dmnsn_delete_tokens(dmnsn_array *tokens) -{ - DMNSN_ARRAY_FOREACH (dmnsn_token *, token, tokens) { - dmnsn_delete_token(*token); - } - dmnsn_delete_array(tokens); -} - -static void -dmnsn_print_token(FILE *file, dmnsn_token token) -{ - const char *tname; - if (token.type == DMNSN_T_LPAREN) { - tname = "\\("; - } else if (token.type == DMNSN_T_RPAREN) { - tname = "\\)"; - } else if (token.type == DMNSN_T_LEX_ERROR) { - tname = "(error)"; - } else { - tname = dmnsn_token_string(token.type); - } - - if (token.value) { - fprintf(file, "(%s \"%s\")", tname, token.value); - } else { - fprintf(file, "%s", tname); - } -} - -void -dmnsn_print_token_sexpr(FILE *file, const dmnsn_array *tokens) -{ - if (dmnsn_array_size(tokens) == 0) { - fprintf(file, "()"); - } else { - fprintf(file, "("); - dmnsn_token *token = dmnsn_array_first(tokens); - dmnsn_print_token(file, *token); - - for (++token; token <= (dmnsn_token *)dmnsn_array_last(tokens); ++token) { - fprintf(file, " "); - dmnsn_print_token(file, *token); - } - - fprintf(file, ")"); - } - - fprintf(file, "\n"); -} diff --git a/dimension/main.c b/dimension/main.c deleted file mode 100644 index 26f131c..0000000 --- a/dimension/main.c +++ /dev/null @@ -1,376 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "tokenize.h" -#include "parse.h" -#include "realize.h" -#include "progressbar.h" -#include "dimension.h" -#include <libgen.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> - -static char *output = NULL, *input = NULL; -static bool free_output = false; -static int width = 640, height = 480; -static int nthreads = 0; -static dmnsn_quality quality = DMNSN_RENDER_FULL; -static int tokenize = 0, parse = 0; - -static void print_usage(FILE *file, const char *arg0); -static void print_version(FILE *file); - -int -main(int argc, char **argv) -{ - /* - * Parse the command-line options - */ - - /* Long-only option codes */ - enum { - DMNSN_OPT_VERSION = 256, - DMNSN_OPT_THREADS, - DMNSN_OPT_QUALITY, - DMNSN_OPT_STRICT - }; - - static struct option long_options[] = { - { "help", no_argument, NULL, '?' }, - { "version", no_argument, NULL, DMNSN_OPT_VERSION }, - { "output", required_argument, NULL, 'o' }, - { "width", required_argument, NULL, 'w' }, - { "height", required_argument, NULL, 'h' }, - { "threads", required_argument, NULL, DMNSN_OPT_THREADS }, - { "quality", required_argument, NULL, DMNSN_OPT_QUALITY }, - { "strict", no_argument, NULL, DMNSN_OPT_STRICT }, - { "tokenize", no_argument, &tokenize, 1 }, - { "parse", no_argument, &parse, 1 }, - { 0, 0, 0, 0 } - }; - - int opt, opt_index; - - while (1) { - opt = getopt_long(argc, argv, "?o:w:h:", long_options, &opt_index); - - if (opt == -1) - break; - - switch (opt) { - case 0: - /* Option set a flag - do nothing here */ - break; - - case '?': - /* '?' is returned as an error code too */ - if (optopt == 0) { - print_usage(stdout, argv[0]); - return EXIT_SUCCESS; - } else { - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } - case DMNSN_OPT_VERSION: - print_version(stdout); - return EXIT_SUCCESS; - - case 'o': - if (output) { - fprintf(stderr, "--output specified more than once!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } else { - output = optarg; - } - break; - - case 'w': - if (!dmnsn_strtoi(&width, optarg, 10) || width <= 0) { - fprintf(stderr, "Invalid argument to --width!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } - case 'h': - if (!dmnsn_strtoi(&height, optarg, 10) || height <= 0) { - fprintf(stderr, "Invalid argument to --height!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } - break; - - case DMNSN_OPT_THREADS: - if (!dmnsn_strtoi(&nthreads, optarg, 10) || nthreads <= 0) { - fprintf(stderr, "Invalid argument to --threads!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } - break; - case DMNSN_OPT_QUALITY: - { - unsigned int iqual; - if (!dmnsn_strtoui(&iqual, optarg, 0)) { - fprintf(stderr, "Invalid argument to --quality!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } - quality = iqual; - break; - } - case DMNSN_OPT_STRICT: - dmnsn_die_on_warnings(true); - break; - - default: - fprintf(stderr, "Invalid command line option!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - }; - } - - if (optind == argc - 1) { - input = argv[optind]; - } else if (optind < argc) { - fprintf(stderr, "Invalid extraneous command line options!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } - - if (!input) { - fprintf(stderr, "No input file specified!\n"); - print_usage(stderr, argv[0]); - return EXIT_FAILURE; - } - - /* - * Now do the work - */ - - /* Open the input file */ - FILE *input_file = fopen(input, "r"); - if (!input_file) { - fprintf(stderr, "Couldn't open input file!\n"); - return EXIT_FAILURE; - } - - /* Debugging option - output the list of tokens as an S-expression */ - if (tokenize) { - dmnsn_array *tokens = dmnsn_tokenize(input_file, input); - if (!tokens) { - fclose(input_file); - fprintf(stderr, "Error tokenizing input file!\n"); - return EXIT_FAILURE; - } - dmnsn_print_token_sexpr(stdout, tokens); - rewind(input_file); - dmnsn_delete_tokens(tokens); - - if (!parse) { - fclose(input_file); - return EXIT_SUCCESS; - } - } - - /* Construct the symbol table */ - dmnsn_symbol_table *symtable = dmnsn_new_symbol_table(); - dmnsn_declare_symbol(symtable, "$file", dmnsn_new_ast_string(input)); - dmnsn_declare_symbol(symtable, "version", dmnsn_new_ast_float(3.6)); - dmnsn_declare_symbol(symtable, "image_width", dmnsn_new_ast_integer(width)); - dmnsn_declare_symbol(symtable, "image_height", dmnsn_new_ast_integer(height)); - - /* Debugging option - output the abstract syntax tree as an S-expression */ - if (parse) { - dmnsn_astree *astree = dmnsn_parse(input_file, symtable); - if (!astree) { - dmnsn_delete_symbol_table(symtable); - fclose(input_file); - fprintf(stderr, "Error parsing input file!\n"); - return EXIT_FAILURE; - } - dmnsn_print_astree_sexpr(stdout, astree); - dmnsn_delete_astree(astree); - - dmnsn_delete_symbol_table(symtable); - fclose(input_file); - return EXIT_SUCCESS; - } - - /* Realize the input */ - - printf("Parsing scene ...\n"); - /* Time the parser */ - dmnsn_timer *parse_timer = dmnsn_new_timer(); - dmnsn_scene *scene = dmnsn_realize(input_file, symtable); - if (!scene) { - fprintf(stderr, "Error realizing input file!\n"); - dmnsn_delete_timer(parse_timer); - dmnsn_delete_symbol_table(symtable); - fclose(input_file); - return EXIT_FAILURE; - } - dmnsn_complete_timer(parse_timer); - - dmnsn_delete_symbol_table(symtable); - fclose(input_file); - - /* Allocate a canvas */ - scene->canvas = dmnsn_new_canvas(width, height); - - /* Set the new number of threads if --threads changed it */ - if (nthreads) - scene->nthreads = nthreads; - - /* Set the render quality */ - scene->quality = quality; - - /* - * Now we render the scene - */ - - /* Generate a default output filename by replacing the extension of the - basename of the input file with ".png" */ - if (!output) { - char *input_copy = dmnsn_strdup(input); - char *base = basename(input_copy); - char *ext = strrchr(base, '.'); - if (ext) { - output = dmnsn_malloc(ext - base + 5); - strncpy(output, base, ext - base + 5); - ext = output + (ext - base); - } else { - size_t len = strlen(base); - output = dmnsn_malloc(len + 5); - strcpy(output, base); - ext = output + len; - } - dmnsn_free(input_copy); - strcpy(ext, ".png"); - free_output = true; - } - - /* Open the output file */ - FILE *output_file = fopen(output, "wb"); - if (free_output) - dmnsn_free(output); - if (!output_file) { - dmnsn_delete_timer(parse_timer); - fprintf(stderr, "Couldn't open output file!"); - return EXIT_FAILURE; - } - - if (dmnsn_png_optimize_canvas(scene->canvas) != 0) { - fprintf(stderr, "WARNING: Couldn't optimize canvas for PNG\n"); - } - - dmnsn_progress *render_progress = dmnsn_raytrace_scene_async(scene); - dmnsn_progressbar(scene->nthreads > 1 - ? "Rendering scene with %u threads" - : "Rendering scene with %u thread", - render_progress, - scene->nthreads); - - if (dmnsn_finish_progress(render_progress) != 0) { - fclose(output_file); - dmnsn_delete_timer(parse_timer); - dmnsn_delete_scene(scene); - fprintf(stderr, "Error rendering scene!\n"); - return EXIT_FAILURE; - } - - /* Time the export */ - dmnsn_timer *export_timer = dmnsn_new_timer(); - dmnsn_progress *output_progress - = dmnsn_png_write_canvas_async(scene->canvas, output_file); - if (!output_progress) { - fclose(output_file); - dmnsn_delete_timer(parse_timer); - dmnsn_delete_scene(scene); - fprintf(stderr, "Couldn't initialize PNG export!\n"); - return EXIT_FAILURE; - } - - dmnsn_progressbar("Writing PNG", output_progress); - - if (dmnsn_finish_progress(output_progress) != 0) { - dmnsn_delete_timer(export_timer); - dmnsn_delete_timer(parse_timer); - fclose(output_file); - dmnsn_delete_scene(scene); - fprintf(stderr, "Couldn't write output!\n"); - return EXIT_FAILURE; - } - fclose(output_file); - dmnsn_complete_timer(export_timer); - - printf("\n" - " Parse time: " DMNSN_TIMER_FORMAT "\n" - " Bounding time: " DMNSN_TIMER_FORMAT "\n" - " Render time: " DMNSN_TIMER_FORMAT "\n" - " Export time: " DMNSN_TIMER_FORMAT "\n", - DMNSN_TIMER_PRINTF(parse_timer), - DMNSN_TIMER_PRINTF(scene->bounding_timer), - DMNSN_TIMER_PRINTF(scene->render_timer), - DMNSN_TIMER_PRINTF(export_timer)); - - dmnsn_delete_timer(export_timer); - dmnsn_delete_timer(parse_timer); - dmnsn_delete_scene(scene); - return EXIT_SUCCESS; -} - -static void -print_usage(FILE *file, const char *arg0) -{ - fprintf(file, - "Usage: %s [OPTIONS...] INPUT_FILE\n\n" - " Main options:\n" - " -?, --help show this help\n" - " --version show the version of %s\n" - " -o, --output=FILE output to FILE\n\n" - " Output options:\n" - " -w, --width=WIDTH set canvas width to WIDTH (default 640)\n" - " -h, --height=HEIGHT set canvas height to HEIGHT (default 480)\n\n" - " Rendering options:\n" - " --threads=THREADS render with THREADS parallel threads\n" - " --quality=QUALITY use the quality setting QUALITY\n" - " --strict treat warnings as errors\n" - " Debugging options:\n" - " --tokenize tokenize the input and print the token list\n" - " --parse parse the input and print the abstract syntax" - " tree\n\n" - " Special options:\n" - " -- indicates the end of the argument list\n\n" - "%s\n" - "%s\n" - "Copyright (C) 2009-2010 Tavian Barnes, <%s>\n" - "Licensed under the GNU General Public License\n", - arg0, - PACKAGE_NAME, - PACKAGE_STRING, - PACKAGE_URL, - PACKAGE_BUGREPORT); -} - -static void -print_version(FILE *file) -{ - fprintf(file, "%s\n", PACKAGE_STRING); -} diff --git a/dimension/parse.c b/dimension/parse.c deleted file mode 100644 index 6651d41..0000000 --- a/dimension/parse.c +++ /dev/null @@ -1,1679 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "parse.h" -#include "utility.h" -#include <errno.h> -#include <fenv.h> -#include <limits.h> -#include <math.h> -#include <stdint.h> -#include <stdlib.h> - -/* - * Symbol table - */ - -dmnsn_symbol_table * -dmnsn_new_symbol_table(void) -{ - dmnsn_symbol_table *symtable = dmnsn_new_array(sizeof(dmnsn_dictionary *)); - dmnsn_push_scope(symtable); - return symtable; -} - -void -dmnsn_delete_symbol_table(dmnsn_symbol_table *symtable) -{ - while (dmnsn_array_size(symtable) > 0) { - dmnsn_pop_scope(symtable); - } - dmnsn_delete_array(symtable); -} - -void -dmnsn_push_scope(dmnsn_symbol_table *symtable) -{ - dmnsn_dictionary *scope = dmnsn_new_dictionary(sizeof(dmnsn_astnode)); - dmnsn_array_push(symtable, &scope); -} - -static void -dmnsn_delete_symbol_table_entry(void *ptr) -{ - dmnsn_astnode *astnode = ptr; - dmnsn_delete_astnode(*astnode); -} - -void dmnsn_pop_scope(dmnsn_symbol_table *symtable) -{ - dmnsn_dictionary *scope; - dmnsn_array_pop(symtable, &scope); - dmnsn_dictionary_apply(scope, dmnsn_delete_symbol_table_entry); - dmnsn_delete_dictionary(scope); -} - -void dmnsn_local_symbol(dmnsn_symbol_table *symtable, - const char *id, dmnsn_astnode value) -{ - ++*value.refcount; - - dmnsn_dictionary *dict; - dmnsn_array_get(symtable, dmnsn_array_size(symtable) - 1, &dict); - dmnsn_astnode *node = dmnsn_dictionary_at(dict, id); - if (node) { - dmnsn_delete_astnode(*node); - *node = value; - } else { - dmnsn_dictionary_insert(dict, id, &value); - } -} - -void -dmnsn_declare_symbol(dmnsn_symbol_table *symtable, - const char *id, dmnsn_astnode value) -{ - ++*value.refcount; - - dmnsn_astnode *node = dmnsn_find_symbol(symtable, id); - if (node) { - /* Always update the most local symbol */ - dmnsn_delete_astnode(*node); - *node = value; - } else { - /* but create new ones at the least local scope */ - dmnsn_dictionary *dict; - dmnsn_array_get(symtable, 0, &dict); - - node = dmnsn_dictionary_at(dict, id); - if (node) { - dmnsn_delete_astnode(*node); - *node = value; - } else { - dmnsn_dictionary_insert(dict, id, &value); - } - } -} - -void -dmnsn_undef_symbol(dmnsn_symbol_table *symtable, const char *id) -{ - DMNSN_ARRAY_FOREACH (dmnsn_dictionary **, dict, symtable) { - dmnsn_astnode *node = dmnsn_dictionary_at(*dict, id); - if (node) { - dmnsn_delete_astnode(*node); - dmnsn_dictionary_remove(*dict, id); - break; - } - } -} - -dmnsn_astnode * -dmnsn_find_symbol(dmnsn_symbol_table *symtable, const char *id) -{ - dmnsn_astnode *symbol = NULL; - - DMNSN_ARRAY_FOREACH_REVERSE (dmnsn_dictionary **, dict, symtable) { - symbol = dmnsn_dictionary_at(*dict, id); - if (symbol) { - if (symbol->type == DMNSN_AST_IDENTIFIER) { - id = symbol->ptr; - } else { - break; - } - } - } - - return symbol; -} - -/* - * Abstract syntax tree - */ - -static dmnsn_astnode -dmnsn_new_astnode(dmnsn_astnode_type type) -{ - dmnsn_astnode astnode = { - .type = type, - .children = NULL, - .ptr = NULL, - .free_fn = NULL, - .refcount = dmnsn_malloc(sizeof(unsigned int)), - .location = { "<environment>", "<environment>", -1, -1, -1, -1, NULL } - }; - - *astnode.refcount = 0; - return astnode; -} - -dmnsn_astnode -dmnsn_new_ast_array(void) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(DMNSN_AST_ARRAY); - astnode.children = dmnsn_new_array(sizeof(dmnsn_astnode)); - return astnode; -} - -static void -dmnsn_make_ast_integer(dmnsn_astnode *astnode, long value) -{ - astnode->type = DMNSN_AST_INTEGER; - astnode->ptr = dmnsn_malloc(sizeof(long)); - *(long *)astnode->ptr = value; -} - -dmnsn_astnode -dmnsn_new_ast_integer(long value) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(DMNSN_AST_INTEGER); - dmnsn_make_ast_integer(&astnode, value); - return astnode; -} - -static void -dmnsn_make_ast_float(dmnsn_astnode *astnode, double value) -{ - astnode->type = DMNSN_AST_FLOAT; - astnode->ptr = dmnsn_malloc(sizeof(double)); - *(double *)astnode->ptr = value; -} - -dmnsn_astnode -dmnsn_new_ast_float(double value) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(DMNSN_AST_FLOAT); - dmnsn_make_ast_float(&astnode, value); - return astnode; -} - -static void -dmnsn_make_ast_ivector(dmnsn_astnode *astnode, - long x, long y, long z, long f, long t) -{ - astnode->type = DMNSN_AST_VECTOR; - if (!astnode->children) - astnode->children = dmnsn_new_array(sizeof(dmnsn_astnode)); - - dmnsn_astnode comp; - - comp = dmnsn_new_ast_integer(x); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_integer(y); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_integer(z); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_integer(f); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_integer(t); - dmnsn_array_push(astnode->children, &comp); -} - -dmnsn_astnode -dmnsn_new_ast_ivector(long x, long y, long z, long f, long t) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(DMNSN_AST_VECTOR); - dmnsn_make_ast_ivector(&astnode, x, y, z, f, t); - return astnode; -} - -static void -dmnsn_make_ast_vector(dmnsn_astnode *astnode, - double x, double y, double z, double f, double t) -{ - astnode->type = DMNSN_AST_VECTOR; - if (!astnode->children) - astnode->children = dmnsn_new_array(sizeof(dmnsn_astnode)); - - dmnsn_astnode comp; - - comp = dmnsn_new_ast_float(x); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_float(y); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_float(z); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_float(f); - dmnsn_array_push(astnode->children, &comp); - - comp = dmnsn_new_ast_float(t); - dmnsn_array_push(astnode->children, &comp); -} - -dmnsn_astnode -dmnsn_new_ast_vector(double x, double y, double z, double f, double t) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(DMNSN_AST_VECTOR); - dmnsn_make_ast_vector(&astnode, x, y, z, f, t); - return astnode; -} - -dmnsn_astnode -dmnsn_new_ast_string(const char *value) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(DMNSN_AST_STRING); - astnode.ptr = dmnsn_strdup(value); - return astnode; -} - -void -dmnsn_delete_astnode(dmnsn_astnode astnode) -{ - if (*astnode.refcount <= 1) { - dmnsn_delete_astree(astnode.children); - if (astnode.free_fn) { - astnode.free_fn(astnode.ptr); - } else { - dmnsn_free(astnode.ptr); - } - dmnsn_free(astnode.refcount); - } else { - --*astnode.refcount; - } -} - -void -dmnsn_delete_astree(dmnsn_astree *astree) -{ - if (astree) { - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, node, astree) { - dmnsn_delete_astnode(*node); - } - dmnsn_delete_array(astree); - } -} - -static dmnsn_astnode -dmnsn_copy_astnode(dmnsn_astnode astnode) -{ - dmnsn_astnode copy = { - .type = astnode.type, - .children = dmnsn_new_array(sizeof(dmnsn_astnode)), - .ptr = NULL, - .refcount = dmnsn_malloc(sizeof(unsigned int)), - .location = astnode.location - }; - - *copy.refcount = 1; - return copy; -} - -static dmnsn_astnode -dmnsn_new_astnode2(dmnsn_astnode_type type, dmnsn_astnode loc, - dmnsn_astnode n1, dmnsn_astnode n2) -{ - dmnsn_astnode astnode = dmnsn_copy_astnode(loc); - astnode.type = type; - dmnsn_array_push(astnode.children, &n1); - dmnsn_array_push(astnode.children, &n2); - return astnode; -} - -/* 5-element vectors */ -#define DMNSN_VECTOR_NELEM 5 - -static dmnsn_astnode -dmnsn_vector_promote(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - dmnsn_astnode promoted = dmnsn_copy_astnode(astnode); - - if (astnode.type == DMNSN_AST_VECTOR) { - dmnsn_astnode component; - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, i, astnode.children) { - component = dmnsn_eval_scalar(*i, symtable); - - if (component.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode(promoted); - return component; - } else { - dmnsn_array_push(promoted.children, &component); - } - } - - while (dmnsn_array_size(promoted.children) < DMNSN_VECTOR_NELEM) { - component = dmnsn_copy_astnode(component); - dmnsn_make_ast_integer(&component, 0); - dmnsn_array_push(promoted.children, &component); - } - } else { - dmnsn_astnode component = dmnsn_eval_scalar(astnode, symtable); - - if (component.type == DMNSN_AST_NONE) { - promoted.type = DMNSN_AST_NONE; - } else { - promoted.type = DMNSN_AST_VECTOR; - while (dmnsn_array_size(promoted.children) < DMNSN_VECTOR_NELEM) { - dmnsn_array_push(promoted.children, &component); - ++*component.refcount; - } - } - - dmnsn_delete_astnode(component); - } - - return promoted; -} - -static void -dmnsn_make_ast_maybe_integer(dmnsn_astnode *ret, double n) -{ - feclearexcept(FE_ALL_EXCEPT); - long l = lrint(n); - if (fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)) { - dmnsn_make_ast_float(ret, n); - } else { - dmnsn_make_ast_integer(ret, l); - } -} - -static dmnsn_astnode -dmnsn_eval_zeroary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - dmnsn_astnode ret = dmnsn_copy_astnode(astnode); - - switch (astnode.type) { - case DMNSN_AST_PI: - dmnsn_make_ast_float(&ret, 4.0*atan(1.0)); - break; - case DMNSN_AST_TRUE: - dmnsn_make_ast_integer(&ret, 1); - break; - case DMNSN_AST_FALSE: - dmnsn_make_ast_integer(&ret, 0); - break; - - case DMNSN_AST_X: - dmnsn_make_ast_ivector(&ret, 1, 0, 0, 0, 0); - break; - case DMNSN_AST_Y: - dmnsn_make_ast_ivector(&ret, 0, 1, 0, 0, 0); - break; - case DMNSN_AST_Z: - dmnsn_make_ast_ivector(&ret, 0, 0, 1, 0, 0); - break; - case DMNSN_AST_T: - dmnsn_make_ast_ivector(&ret, 0, 0, 0, 1, 0); - break; - - default: - dmnsn_diagnostic(astnode.location, "invalid constant '%s'", - dmnsn_astnode_string(astnode.type)); - ret.type = DMNSN_AST_NONE; - break; - } - - return ret; -} - -static dmnsn_astnode -dmnsn_eval_unary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - dmnsn_astnode rhs; - dmnsn_array_get(astnode.children, 0, &rhs); - rhs = dmnsn_eval(rhs, symtable); - - dmnsn_astnode ret; - - if (rhs.type == DMNSN_AST_NONE) { - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_NONE; - } else if (rhs.type == DMNSN_AST_VECTOR) { - switch (astnode.type) { - case DMNSN_AST_DOT_X: - dmnsn_array_get(rhs.children, 0, &ret); - ++*ret.refcount; - break; - case DMNSN_AST_DOT_Y: - dmnsn_array_get(rhs.children, 1, &ret); - ++*ret.refcount; - break; - case DMNSN_AST_DOT_Z: - dmnsn_array_get(rhs.children, 2, &ret); - ++*ret.refcount; - break; - case DMNSN_AST_DOT_T: - dmnsn_array_get(rhs.children, 3, &ret); - ++*ret.refcount; - break; - case DMNSN_AST_DOT_TRANSMIT: - dmnsn_array_get(rhs.children, 4, &ret); - ++*ret.refcount; - break; - - case DMNSN_AST_VLENGTH: - { - dmnsn_astnode dot = dmnsn_copy_astnode(astnode); - dot.type = DMNSN_AST_VDOT; - *rhs.refcount += 2; - dmnsn_array_push(dot.children, &rhs); - dmnsn_array_push(dot.children, &rhs); - - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - rewrite.type = DMNSN_AST_SQRT; - dmnsn_array_push(rewrite.children, &dot); - - ret = dmnsn_eval(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - case DMNSN_AST_VNORMALIZE: - { - dmnsn_astnode norm = dmnsn_copy_astnode(astnode); - norm.type = DMNSN_AST_VLENGTH; - ++*rhs.refcount; - dmnsn_array_push(norm.children, &rhs); - - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - rewrite.type = DMNSN_AST_DIV; - ++*rhs.refcount; - dmnsn_array_push(rewrite.children, &rhs); - dmnsn_array_push(rewrite.children, &norm); - - ret = dmnsn_eval(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - - default: - { - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_VECTOR; - - dmnsn_astnode op = dmnsn_copy_astnode(astnode); - dmnsn_array_resize(op.children, 1); - for (size_t i = 0; i < DMNSN_VECTOR_NELEM; ++i) { - dmnsn_array_get(rhs.children, i, dmnsn_array_at(op.children, 0)); - dmnsn_astnode temp = dmnsn_eval_unary(op, symtable); - dmnsn_array_set(ret.children, i, &temp); - } - - dmnsn_delete_array(op.children); - op.children = NULL; - dmnsn_delete_astnode(op); - break; - } - } - } else if (rhs.type == DMNSN_AST_INTEGER) { - long n = *(long *)rhs.ptr; - ret = dmnsn_copy_astnode(astnode); - - switch (astnode.type) { - case DMNSN_AST_DOT_X: - case DMNSN_AST_DOT_Y: - case DMNSN_AST_DOT_Z: - case DMNSN_AST_DOT_T: - case DMNSN_AST_DOT_TRANSMIT: - dmnsn_make_ast_integer(&ret, n); - break; - - case DMNSN_AST_NEGATE: - if ((n >= 0 && LONG_MIN + n <= 0) || (n < 0 && LONG_MAX + n >= 0)) { - dmnsn_make_ast_integer(&ret, -n); - } else { - dmnsn_make_ast_float(&ret, -(double)n); - } - break; - - case DMNSN_AST_NOT: - dmnsn_make_ast_integer(&ret, !n); - break; - - case DMNSN_AST_ABS: - if (n >= 0 || LONG_MAX + n >= 0) { - dmnsn_make_ast_integer(&ret, labs(n)); - } else { - dmnsn_make_ast_float(&ret, fabs(n)); - } - break; - case DMNSN_AST_ACOS: - dmnsn_make_ast_float(&ret, acos(n)); - break; - case DMNSN_AST_ACOSH: - dmnsn_make_ast_float(&ret, acosh(n)); - break; - case DMNSN_AST_ASIN: - dmnsn_make_ast_float(&ret, asin(n)); - break; - case DMNSN_AST_ASINH: - dmnsn_make_ast_float(&ret, asinh(n)); - break; - case DMNSN_AST_ATAN: - dmnsn_make_ast_float(&ret, atan(n)); - break; - case DMNSN_AST_ATANH: - dmnsn_make_ast_float(&ret, atanh(n)); - break; - case DMNSN_AST_CEIL: - dmnsn_make_ast_integer(&ret, n); - break; - case DMNSN_AST_COS: - dmnsn_make_ast_float(&ret, cos(n)); - break; - case DMNSN_AST_COSH: - dmnsn_make_ast_float(&ret, cosh(n)); - break; - case DMNSN_AST_DEGREES: - dmnsn_make_ast_float(&ret, dmnsn_degrees(n)); - break; - case DMNSN_AST_EXP: - dmnsn_make_ast_float(&ret, exp(n)); - break; - case DMNSN_AST_FLOOR: - dmnsn_make_ast_integer(&ret, n); - break; - case DMNSN_AST_INT: - dmnsn_make_ast_integer(&ret, n); - break; - case DMNSN_AST_LN: - dmnsn_make_ast_float(&ret, log(n)); - break; - case DMNSN_AST_LOG: - dmnsn_make_ast_float(&ret, log(n)/log(10.0)); - break; - case DMNSN_AST_RADIANS: - dmnsn_make_ast_float(&ret, dmnsn_radians(n)); - break; - case DMNSN_AST_SIN: - dmnsn_make_ast_float(&ret, sin(n)); - break; - case DMNSN_AST_SINH: - dmnsn_make_ast_float(&ret, sinh(n)); - break; - case DMNSN_AST_SQRT: - dmnsn_make_ast_float(&ret, sqrt(n)); - break; - case DMNSN_AST_TAN: - dmnsn_make_ast_float(&ret, tan(n)); - break; - case DMNSN_AST_TANH: - dmnsn_make_ast_float(&ret, tanh(n)); - break; - case DMNSN_AST_VLENGTH: - dmnsn_make_ast_float(&ret, sqrt(3.0*n*n)); - break; - case DMNSN_AST_VNORMALIZE: - { - double elem = 1.0/sqrt(DMNSN_VECTOR_NELEM); - dmnsn_make_ast_vector(&ret, elem, elem, elem, elem, elem); - break; - } - - default: - dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s", - dmnsn_astnode_string(astnode.type), - dmnsn_astnode_string(rhs.type)); - ret.type = DMNSN_AST_NONE; - break; - } - } else if (rhs.type == DMNSN_AST_FLOAT) { - double n = *(double *)rhs.ptr; - ret = dmnsn_copy_astnode(astnode); - - switch (astnode.type) { - case DMNSN_AST_DOT_X: - case DMNSN_AST_DOT_Y: - case DMNSN_AST_DOT_Z: - case DMNSN_AST_DOT_T: - case DMNSN_AST_DOT_TRANSMIT: - dmnsn_make_ast_float(&ret, n); - break; - - case DMNSN_AST_NEGATE: - dmnsn_make_ast_float(&ret, -n); - break; - - case DMNSN_AST_NOT: - dmnsn_make_ast_integer(&ret, !n); - break; - - case DMNSN_AST_ABS: - dmnsn_make_ast_float(&ret, fabs(n)); - break; - case DMNSN_AST_ACOS: - dmnsn_make_ast_float(&ret, acos(n)); - break; - case DMNSN_AST_ACOSH: - dmnsn_make_ast_float(&ret, acosh(n)); - break; - case DMNSN_AST_ASIN: - dmnsn_make_ast_float(&ret, asin(n)); - break; - case DMNSN_AST_ASINH: - dmnsn_make_ast_float(&ret, asinh(n)); - break; - case DMNSN_AST_ATAN: - dmnsn_make_ast_float(&ret, atan(n)); - break; - case DMNSN_AST_ATANH: - dmnsn_make_ast_float(&ret, atanh(n)); - break; - case DMNSN_AST_CEIL: - dmnsn_make_ast_maybe_integer(&ret, ceil(n)); - break; - case DMNSN_AST_COS: - dmnsn_make_ast_float(&ret, cos(n)); - break; - case DMNSN_AST_COSH: - dmnsn_make_ast_float(&ret, cosh(n)); - break; - case DMNSN_AST_DEGREES: - dmnsn_make_ast_float(&ret, dmnsn_degrees(n)); - break; - case DMNSN_AST_EXP: - dmnsn_make_ast_float(&ret, exp(n)); - break; - case DMNSN_AST_FLOOR: - dmnsn_make_ast_maybe_integer(&ret, floor(n)); - break; - case DMNSN_AST_INT: - dmnsn_make_ast_maybe_integer(&ret, trunc(n)); - break; - case DMNSN_AST_LN: - dmnsn_make_ast_float(&ret, log(n)); - break; - case DMNSN_AST_LOG: - dmnsn_make_ast_float(&ret, log(n)/log(10.0)); - break; - case DMNSN_AST_RADIANS: - dmnsn_make_ast_float(&ret, dmnsn_radians(n)); - break; - case DMNSN_AST_SIN: - dmnsn_make_ast_float(&ret, sin(n)); - break; - case DMNSN_AST_SINH: - dmnsn_make_ast_float(&ret, sinh(n)); - break; - case DMNSN_AST_SQRT: - dmnsn_make_ast_float(&ret, sqrt(n)); - break; - case DMNSN_AST_TAN: - dmnsn_make_ast_float(&ret, tan(n)); - break; - case DMNSN_AST_TANH: - dmnsn_make_ast_float(&ret, tanh(n)); - break; - case DMNSN_AST_VLENGTH: - dmnsn_make_ast_float(&ret, sqrt(3.0*n*n)); - break; - case DMNSN_AST_VNORMALIZE: - { - double elem = 1.0/sqrt(DMNSN_VECTOR_NELEM); - dmnsn_make_ast_vector(&ret, elem, elem, elem, elem, elem); - break; - } - - default: - dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s", - dmnsn_astnode_string(astnode.type), - dmnsn_astnode_string(rhs.type)); - ret.type = DMNSN_AST_NONE; - break; - } - } else if (rhs.type == DMNSN_AST_STRING) { - ret = dmnsn_copy_astnode(astnode); - - switch (astnode.type) { - case DMNSN_AST_ASC: - dmnsn_make_ast_integer(&ret, ((char *)rhs.ptr)[0]); - break; - case DMNSN_AST_STRLEN: - dmnsn_make_ast_integer(&ret, strlen(rhs.ptr)); - break; - case DMNSN_AST_VAL: - { - long l; - if (dmnsn_strtol(&l, rhs.ptr, 0)) { - dmnsn_make_ast_integer(&ret, l); - } else { - double d; - if (dmnsn_strtod(&d, rhs.ptr)) { - dmnsn_make_ast_float(&ret, d); - } else if (errno == ERANGE) { - dmnsn_diagnostic(astnode.location, "float value overflowed"); - ret.type = DMNSN_AST_NONE; - } else { - dmnsn_diagnostic(astnode.location, "invalid numeric string '%s'", - (const char *)rhs.ptr); - ret.type = DMNSN_AST_NONE; - } - } - break; - } - - default: - dmnsn_diagnostic(astnode.location, "invalid unary operator '%s' on %s", - dmnsn_astnode_string(astnode.type), - dmnsn_astnode_string(rhs.type)); - ret.type = DMNSN_AST_NONE; - break; - } - } else { - dmnsn_diagnostic(rhs.location, "expected %s or %s or %s; found %s", - dmnsn_astnode_string(DMNSN_AST_INTEGER), - dmnsn_astnode_string(DMNSN_AST_FLOAT), - dmnsn_astnode_string(DMNSN_AST_STRING), - dmnsn_astnode_string(rhs.type)); - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_NONE; - } - - dmnsn_delete_astnode(rhs); - return ret; -} - -static dmnsn_astnode -dmnsn_eval_binary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - dmnsn_astnode lhs, rhs; - dmnsn_array_get(astnode.children, 0, &lhs); - dmnsn_array_get(astnode.children, 1, &rhs); - lhs = dmnsn_eval(lhs, symtable); - rhs = dmnsn_eval(rhs, symtable); - - dmnsn_astnode ret; - - if (lhs.type == DMNSN_AST_NONE || rhs.type == DMNSN_AST_NONE) { - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_NONE; - } else if (lhs.type == DMNSN_AST_VECTOR || rhs.type == DMNSN_AST_VECTOR) { - dmnsn_astnode oldlhs = lhs, oldrhs = rhs; - lhs = dmnsn_vector_promote(lhs, symtable); - rhs = dmnsn_vector_promote(rhs, symtable); - dmnsn_delete_astnode(oldlhs); - dmnsn_delete_astnode(oldrhs); - - if (lhs.type == DMNSN_AST_NONE || rhs.type == DMNSN_AST_NONE) { - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_NONE; - dmnsn_delete_astnode(lhs); - dmnsn_delete_astnode(rhs); - return ret; - } - - switch (astnode.type) { - case DMNSN_AST_EQUAL: - { - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - - dmnsn_astnode l, r; - dmnsn_array_get(lhs.children, 0, &l); - dmnsn_array_get(rhs.children, 0, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(rewrite.children, &l); - dmnsn_array_push(rewrite.children, &r); - - for (size_t i = 1; i < DMNSN_VECTOR_NELEM; ++i) { - dmnsn_astnode temp = dmnsn_copy_astnode(astnode); - dmnsn_array_get(lhs.children, i, &l); - dmnsn_array_get(rhs.children, i, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(temp.children, &l); - dmnsn_array_push(temp.children, &r); - - dmnsn_astnode next = dmnsn_copy_astnode(astnode); - next.type = DMNSN_AST_AND; - dmnsn_array_push(next.children, &rewrite); - dmnsn_array_push(next.children, &temp); - rewrite = next; - } - - ret = dmnsn_eval_binary(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - - case DMNSN_AST_NOT_EQUAL: - { - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - - dmnsn_astnode l, r; - dmnsn_array_get(lhs.children, 0, &l); - dmnsn_array_get(rhs.children, 0, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(rewrite.children, &l); - dmnsn_array_push(rewrite.children, &r); - - for (size_t i = 1; i < DMNSN_VECTOR_NELEM; ++i) { - dmnsn_astnode temp = dmnsn_copy_astnode(astnode); - dmnsn_array_get(lhs.children, i, &l); - dmnsn_array_get(rhs.children, i, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(temp.children, &l); - dmnsn_array_push(temp.children, &r); - - dmnsn_astnode next = dmnsn_copy_astnode(astnode); - next.type = DMNSN_AST_OR; - dmnsn_array_push(next.children, &rewrite); - dmnsn_array_push(next.children, &temp); - rewrite = next; - } - - ret = dmnsn_eval_binary(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - - case DMNSN_AST_AND: - { - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - rewrite.type = DMNSN_AST_OR; - - dmnsn_astnode l, r; - dmnsn_array_get(lhs.children, 0, &l); - dmnsn_array_get(rhs.children, 0, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(rewrite.children, &l); - dmnsn_array_push(rewrite.children, &r); - - for (size_t i = 1; i < DMNSN_VECTOR_NELEM; ++i) { - dmnsn_astnode temp = dmnsn_copy_astnode(astnode); - temp.type = DMNSN_AST_OR; - dmnsn_array_get(lhs.children, i, &l); - dmnsn_array_get(rhs.children, i, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(temp.children, &l); - dmnsn_array_push(temp.children, &r); - - dmnsn_astnode next = dmnsn_copy_astnode(astnode); - next.type = DMNSN_AST_AND; - dmnsn_array_push(next.children, &rewrite); - dmnsn_array_push(next.children, &temp); - rewrite = next; - } - - ret = dmnsn_eval_binary(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - - case DMNSN_AST_OR: - { - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - rewrite.type = DMNSN_AST_OR; - - dmnsn_astnode l, r; - dmnsn_array_get(lhs.children, 0, &l); - dmnsn_array_get(rhs.children, 0, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(rewrite.children, &l); - dmnsn_array_push(rewrite.children, &r); - - for (size_t i = 1; i < DMNSN_VECTOR_NELEM; ++i) { - dmnsn_astnode temp = dmnsn_copy_astnode(astnode); - temp.type = DMNSN_AST_OR; - dmnsn_array_get(lhs.children, i, &l); - dmnsn_array_get(rhs.children, i, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(temp.children, &l); - dmnsn_array_push(temp.children, &r); - - dmnsn_astnode next = dmnsn_copy_astnode(astnode); - next.type = DMNSN_AST_OR; - dmnsn_array_push(next.children, &rewrite); - dmnsn_array_push(next.children, &temp); - rewrite = next; - } - - ret = dmnsn_eval_binary(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - - case DMNSN_AST_LESS: - case DMNSN_AST_LESS_EQUAL: - case DMNSN_AST_GREATER: - case DMNSN_AST_GREATER_EQUAL: - dmnsn_diagnostic(astnode.location, - "invalid comparison operator '%s' between vectors", - dmnsn_astnode_string(astnode.type)); - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_NONE; - break; - - case DMNSN_AST_VAXIS_ROTATE: - { - dmnsn_astnode rx, ry, rz; - dmnsn_array_get(lhs.children, 0, &rx); - dmnsn_array_get(lhs.children, 1, &ry); - dmnsn_array_get(lhs.children, 2, &rz); - dmnsn_astnode ax, ay, az; - dmnsn_array_get(rhs.children, 0, &ax); - dmnsn_array_get(rhs.children, 1, &ay); - dmnsn_array_get(rhs.children, 2, &az); - - dmnsn_vector r = dmnsn_new_vector( - rx.type == DMNSN_AST_INTEGER ? *(long *)rx.ptr : *(double *)rx.ptr, - ry.type == DMNSN_AST_INTEGER ? *(long *)ry.ptr : *(double *)ry.ptr, - rz.type == DMNSN_AST_INTEGER ? *(long *)rz.ptr : *(double *)rz.ptr - ); - dmnsn_vector axis = dmnsn_new_vector( - ax.type == DMNSN_AST_INTEGER ? *(long *)ax.ptr : *(double *)ax.ptr, - ay.type == DMNSN_AST_INTEGER ? *(long *)ay.ptr : *(double *)ay.ptr, - az.type == DMNSN_AST_INTEGER ? *(long *)az.ptr : *(double *)az.ptr - ); - - axis = dmnsn_vector_mul(dmnsn_radians(1.0), axis); - r = dmnsn_transform_vector(dmnsn_rotation_matrix(axis), r); - - ret = dmnsn_copy_astnode(astnode); - dmnsn_make_ast_vector(&ret, r.x, r.y, r.z, 0.0, 0.0); - break; - } - case DMNSN_AST_VCROSS: - { - dmnsn_astnode ux, uy, uz; - dmnsn_array_get(lhs.children, 0, &ux); - dmnsn_array_get(lhs.children, 1, &uy); - dmnsn_array_get(lhs.children, 2, &uz); - *ux.refcount += 2; - *uy.refcount += 2; - *uz.refcount += 2; - dmnsn_astnode vx, vy, vz; - dmnsn_array_get(rhs.children, 0, &vx); - dmnsn_array_get(rhs.children, 1, &vy); - dmnsn_array_get(rhs.children, 2, &vz); - *vx.refcount += 2; - *vy.refcount += 2; - *vz.refcount += 2; - - dmnsn_astnode uvx = dmnsn_new_astnode2( - DMNSN_AST_SUB, astnode, - dmnsn_new_astnode2(DMNSN_AST_MUL, astnode, uy, vz), - dmnsn_new_astnode2(DMNSN_AST_MUL, astnode, uz, vy) - ); - dmnsn_astnode uvy = dmnsn_new_astnode2( - DMNSN_AST_SUB, astnode, - dmnsn_new_astnode2(DMNSN_AST_MUL, astnode, uz, vx), - dmnsn_new_astnode2(DMNSN_AST_MUL, astnode, ux, vz) - ); - dmnsn_astnode uvz = dmnsn_new_astnode2( - DMNSN_AST_SUB, astnode, - dmnsn_new_astnode2(DMNSN_AST_MUL, astnode, ux, vy), - dmnsn_new_astnode2(DMNSN_AST_MUL, astnode, uy, vx) - ); - - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - rewrite.type = DMNSN_AST_VECTOR; - dmnsn_array_push(rewrite.children, &uvx); - dmnsn_array_push(rewrite.children, &uvy); - dmnsn_array_push(rewrite.children, &uvz); - - ret = dmnsn_eval(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - case DMNSN_AST_VDOT: - { - dmnsn_astnode rewrite = dmnsn_copy_astnode(astnode); - rewrite.type = DMNSN_AST_MUL; - - dmnsn_astnode l, r; - dmnsn_array_get(lhs.children, 0, &l); - dmnsn_array_get(rhs.children, 0, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(rewrite.children, &l); - dmnsn_array_push(rewrite.children, &r); - - for (size_t i = 1; i < 3; ++i) { - dmnsn_astnode temp = dmnsn_copy_astnode(astnode); - temp.type = DMNSN_AST_MUL; - dmnsn_array_get(lhs.children, i, &l); - dmnsn_array_get(rhs.children, i, &r); - ++*l.refcount; - ++*r.refcount; - dmnsn_array_push(temp.children, &l); - dmnsn_array_push(temp.children, &r); - - dmnsn_astnode next = dmnsn_copy_astnode(astnode); - next.type = DMNSN_AST_ADD; - dmnsn_array_push(next.children, &rewrite); - dmnsn_array_push(next.children, &temp); - rewrite = next; - } - - ret = dmnsn_eval_binary(rewrite, symtable); - dmnsn_delete_astnode(rewrite); - break; - } - case DMNSN_AST_VROTATE: - { - dmnsn_astnode rx, ry, rz; - dmnsn_array_get(lhs.children, 0, &rx); - dmnsn_array_get(lhs.children, 1, &ry); - dmnsn_array_get(lhs.children, 2, &rz); - dmnsn_astnode ax, ay, az; - dmnsn_array_get(rhs.children, 0, &ax); - dmnsn_array_get(rhs.children, 1, &ay); - dmnsn_array_get(rhs.children, 2, &az); - - dmnsn_vector r = dmnsn_new_vector( - rx.type == DMNSN_AST_INTEGER ? *(long *)rx.ptr : *(double *)rx.ptr, - ry.type == DMNSN_AST_INTEGER ? *(long *)ry.ptr : *(double *)ry.ptr, - rz.type == DMNSN_AST_INTEGER ? *(long *)rz.ptr : *(double *)rz.ptr - ); - dmnsn_vector axis = dmnsn_new_vector( - ax.type == DMNSN_AST_INTEGER ? *(long *)ax.ptr : *(double *)ax.ptr, - ay.type == DMNSN_AST_INTEGER ? *(long *)ay.ptr : *(double *)ay.ptr, - az.type == DMNSN_AST_INTEGER ? *(long *)az.ptr : *(double *)az.ptr - ); - - axis = dmnsn_vector_mul(dmnsn_radians(1.0), axis); - - r = dmnsn_transform_vector( - dmnsn_rotation_matrix(dmnsn_new_vector(axis.x, 0.0, 0.0)), - r - ); - r = dmnsn_transform_vector( - dmnsn_rotation_matrix(dmnsn_new_vector(0.0, axis.y, 0.0)), - r - ); - r = dmnsn_transform_vector( - dmnsn_rotation_matrix(dmnsn_new_vector(0.0, 0.0, axis.z)), - r - ); - - ret = dmnsn_copy_astnode(astnode); - dmnsn_make_ast_vector(&ret, r.x, r.y, r.z, 0.0, 0.0); - break; - } - - default: - { - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_VECTOR; - - dmnsn_astnode op = dmnsn_copy_astnode(astnode); - dmnsn_array_resize(op.children, 2); - for (size_t i = 0; i < DMNSN_VECTOR_NELEM; ++i) { - dmnsn_array_get(lhs.children, i, dmnsn_array_at(op.children, 0)); - dmnsn_array_get(rhs.children, i, dmnsn_array_at(op.children, 1)); - dmnsn_astnode temp = dmnsn_eval_binary(op, symtable); - dmnsn_array_set(ret.children, i, &temp); - } - - dmnsn_delete_array(op.children); - op.children = NULL; - dmnsn_delete_astnode(op); - break; - } - } - } else if (lhs.type == DMNSN_AST_STRING && rhs.type == DMNSN_AST_STRING) { - ret = dmnsn_copy_astnode(astnode); - - switch (astnode.type) { - case DMNSN_AST_STRCMP: - dmnsn_make_ast_integer(&ret, strcmp(lhs.ptr, rhs.ptr)); - break; - - default: - dmnsn_diagnostic(astnode.location, - "invalid binary operator '%s' on %s and %s", - dmnsn_astnode_string(astnode.type), - dmnsn_astnode_string(lhs.type), - dmnsn_astnode_string(rhs.type)); - ret.type = DMNSN_AST_NONE; - break; - } - } else if (lhs.type == DMNSN_AST_INTEGER && rhs.type == DMNSN_AST_INTEGER) { - ret = dmnsn_copy_astnode(astnode); - - long l, r; - l = *(long *)lhs.ptr; - r = *(long *)rhs.ptr; - - switch (astnode.type) { - case DMNSN_AST_ADD: - if ((r < 0 && LONG_MIN - r <= l) || (r >= 0 && LONG_MAX - r >= l)) { - dmnsn_make_ast_integer(&ret, l + r); - } else { - dmnsn_make_ast_float(&ret, (double)l + r); - } - break; - case DMNSN_AST_SUB: - if ((r >= 0 && LONG_MIN + r <= l) || (r < 0 && LONG_MAX + r >= l)) { - dmnsn_make_ast_integer(&ret, l - r); - } else { - dmnsn_make_ast_float(&ret, (double)l - r); - } - break; - case DMNSN_AST_MUL: - { -#if (ULONG_MAX > 4294967295) - __int128_t prod = l; -#else - int64_t prod = l; -#endif - prod *= r; - if (prod >= LONG_MIN && prod <= LONG_MAX) { - dmnsn_make_ast_integer(&ret, prod); - } else { - dmnsn_make_ast_float(&ret, prod); - } - break; - } - case DMNSN_AST_DIV: - if (r == -1 - && ((l >= 0 && LONG_MIN + l <= 0) || (l < 0 && LONG_MAX + l >= 0))) - { - dmnsn_make_ast_float(&ret, -(double)l); - } else if (r == 0) { - dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); - dmnsn_make_ast_float(&ret, (double)l/0.0); - } else if (l%r == 0) { - dmnsn_make_ast_integer(&ret, l/r); - } else { - dmnsn_make_ast_float(&ret, (double)l/(double)r); - } - break; - - case DMNSN_AST_EQUAL: - dmnsn_make_ast_integer(&ret, l == r); - break; - case DMNSN_AST_NOT_EQUAL: - dmnsn_make_ast_integer(&ret, l != r); - break; - case DMNSN_AST_LESS: - dmnsn_make_ast_integer(&ret, l < r); - break; - case DMNSN_AST_LESS_EQUAL: - dmnsn_make_ast_integer(&ret, l <= r); - break; - case DMNSN_AST_GREATER: - dmnsn_make_ast_integer(&ret, l > r); - break; - case DMNSN_AST_GREATER_EQUAL: - dmnsn_make_ast_integer(&ret, l >= r); - break; - case DMNSN_AST_AND: - dmnsn_make_ast_integer(&ret, l && r); - break; - case DMNSN_AST_OR: - dmnsn_make_ast_integer(&ret, l || r); - break; - - case DMNSN_AST_ATAN2: - dmnsn_make_ast_float(&ret, atan2(l, r)); - break; - case DMNSN_AST_INT_DIV: - if (r == -1 - && ((l >= 0 && LONG_MIN + l <= 0) || (l < 0 && LONG_MAX + l >= 0))) - { - dmnsn_make_ast_float(&ret, -(double)l); - } else if (r == 0) { - dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); - dmnsn_make_ast_float(&ret, (double)l/0.0); - } else { - dmnsn_make_ast_integer(&ret, l/r); - } - break; - case DMNSN_AST_MAX: - dmnsn_make_ast_integer(&ret, l > r ? l : r); - break; - case DMNSN_AST_MIN: - dmnsn_make_ast_integer(&ret, l < r ? l : r); - break; - case DMNSN_AST_MOD: - if (r == -1) { - /* LONG_MIN % -1 is potentially an overflow */ - dmnsn_make_ast_integer(&ret, 0); - } else if (r == 0) { - dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); - dmnsn_make_ast_float(&ret, fmod(l, 0.0)); - } else { - dmnsn_make_ast_integer(&ret, l%r); - } - break; - case DMNSN_AST_POW: - dmnsn_make_ast_float(&ret, pow(l, r)); - break; - case DMNSN_AST_VCROSS: - dmnsn_make_ast_integer(&ret, 0); - break; - case DMNSN_AST_VDOT: - dmnsn_make_ast_integer(&ret, 3*l*r); - break; - case DMNSN_AST_VROTATE: - ret.type = DMNSN_AST_VECTOR; - *lhs.refcount += 3; - dmnsn_array_push(ret.children, &lhs); - dmnsn_array_push(ret.children, &lhs); - dmnsn_array_push(ret.children, &lhs); - break; - - default: - dmnsn_diagnostic(astnode.location, - "invalid binary operator '%s' on %s and %s", - dmnsn_astnode_string(astnode.type), - dmnsn_astnode_string(lhs.type), - dmnsn_astnode_string(rhs.type)); - ret.type = DMNSN_AST_NONE; - break; - } - } else { - ret = dmnsn_copy_astnode(astnode); - - double l, r; - - if (lhs.type == DMNSN_AST_INTEGER) { - l = *(long *)lhs.ptr; - } else if (lhs.type == DMNSN_AST_FLOAT) { - l = *(double *)lhs.ptr; - } else { - dmnsn_diagnostic(lhs.location, "expected %s or %s; found %s", - dmnsn_astnode_string(DMNSN_AST_INTEGER), - dmnsn_astnode_string(DMNSN_AST_FLOAT), - dmnsn_astnode_string(lhs.type)); - ret.type = DMNSN_AST_NONE; - dmnsn_delete_astnode(lhs); - dmnsn_delete_astnode(rhs); - return ret; - } - - if (rhs.type == DMNSN_AST_INTEGER) { - r = *(long *)rhs.ptr; - } else if (rhs.type == DMNSN_AST_FLOAT) { - r = *(double *)rhs.ptr; - } else { - dmnsn_diagnostic(rhs.location, "expected %s or %s; found %s", - dmnsn_astnode_string(DMNSN_AST_INTEGER), - dmnsn_astnode_string(DMNSN_AST_FLOAT), - dmnsn_astnode_string(rhs.type)); - ret.type = DMNSN_AST_NONE; - dmnsn_delete_astnode(lhs); - dmnsn_delete_astnode(rhs); - return ret; - } - - switch (astnode.type) { - case DMNSN_AST_ADD: - dmnsn_make_ast_float(&ret, l + r); - break; - case DMNSN_AST_SUB: - dmnsn_make_ast_float(&ret, l - r); - break; - case DMNSN_AST_MUL: - dmnsn_make_ast_float(&ret, l*r); - break; - case DMNSN_AST_DIV: - if (r == 0.0) - dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); - dmnsn_make_ast_float(&ret, l/r); - break; - - case DMNSN_AST_EQUAL: - dmnsn_make_ast_integer(&ret, fabs(l - r) < dmnsn_epsilon); - break; - case DMNSN_AST_NOT_EQUAL: - dmnsn_make_ast_integer(&ret, fabs(l - r) >= dmnsn_epsilon); - break; - case DMNSN_AST_LESS: - dmnsn_make_ast_integer(&ret, l < r); - break; - case DMNSN_AST_LESS_EQUAL: - dmnsn_make_ast_integer(&ret, l <= r); - break; - case DMNSN_AST_GREATER: - dmnsn_make_ast_integer(&ret, l > r); - break; - case DMNSN_AST_GREATER_EQUAL: - dmnsn_make_ast_integer(&ret, l >= r); - break; - case DMNSN_AST_AND: - dmnsn_make_ast_integer(&ret, fabs(l) >= dmnsn_epsilon - && fabs(r) >= dmnsn_epsilon); - break; - case DMNSN_AST_OR: - dmnsn_make_ast_integer(&ret, fabs(l) >= dmnsn_epsilon - || fabs(r) >= dmnsn_epsilon); - break; - - case DMNSN_AST_ATAN2: - dmnsn_make_ast_float(&ret, atan2(l, r)); - break; - case DMNSN_AST_INT_DIV: - if (r == 0.0) - dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); - dmnsn_make_ast_maybe_integer(&ret, trunc(l/r)); - break; - case DMNSN_AST_MAX: - if (l > r) { - if (lhs.type == DMNSN_AST_INTEGER) { - dmnsn_make_ast_maybe_integer(&ret, l); - } else { - dmnsn_make_ast_float(&ret, l); - } - } else { - if (rhs.type == DMNSN_AST_INTEGER) { - dmnsn_make_ast_maybe_integer(&ret, r); - } else { - dmnsn_make_ast_float(&ret, r); - } - } - break; - case DMNSN_AST_MIN: - if (l < r) { - if (lhs.type == DMNSN_AST_INTEGER) { - dmnsn_make_ast_maybe_integer(&ret, l); - } else { - dmnsn_make_ast_float(&ret, l); - } - } else { - if (rhs.type == DMNSN_AST_INTEGER) { - dmnsn_make_ast_maybe_integer(&ret, r); - } else { - dmnsn_make_ast_float(&ret, r); - } - } - break; - case DMNSN_AST_MOD: - if (r == 0.0) - dmnsn_diagnostic(astnode.location, "WARNING: division by zero"); - dmnsn_make_ast_float(&ret, fmod(l, r)); - break; - case DMNSN_AST_POW: - dmnsn_make_ast_float(&ret, pow(l, r)); - break; - case DMNSN_AST_VCROSS: - dmnsn_make_ast_integer(&ret, 0); - break; - case DMNSN_AST_VDOT: - dmnsn_make_ast_float(&ret, 3.0*l*r); - break; - case DMNSN_AST_VROTATE: - ret.type = DMNSN_AST_VECTOR; - *lhs.refcount += 3; - dmnsn_array_push(ret.children, &lhs); - dmnsn_array_push(ret.children, &lhs); - dmnsn_array_push(ret.children, &lhs); - break; - - default: - dmnsn_diagnostic(astnode.location, - "invalid binary operator '%s' on %s and %s", - dmnsn_astnode_string(astnode.type), - dmnsn_astnode_string(lhs.type), - dmnsn_astnode_string(rhs.type)); - ret.type = DMNSN_AST_NONE; - break; - } - } - - dmnsn_delete_astnode(lhs); - dmnsn_delete_astnode(rhs); - return ret; -} - -static dmnsn_astnode -dmnsn_eval_ternary(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - dmnsn_astnode test, iftrue, iffalse, ret; - dmnsn_array_get(astnode.children, 0, &test); - dmnsn_array_get(astnode.children, 1, &iftrue); - dmnsn_array_get(astnode.children, 2, &iffalse); - test = dmnsn_eval_scalar(test, symtable); - - switch (astnode.type) { - case DMNSN_AST_TERNARY: - dmnsn_assert(test.type == DMNSN_AST_INTEGER, - "Conditional expression evaluated to non-integer."); - ret = dmnsn_eval(*(long *)test.ptr ? iftrue : iffalse, symtable); - break; - - default: - dmnsn_diagnostic(astnode.location, "invalid ternary operator '%s'", - dmnsn_astnode_string(astnode.type)); - ret = dmnsn_copy_astnode(astnode); - ret.type = DMNSN_AST_NONE; - break; - } - - dmnsn_delete_astnode(test); - return ret; -} - -dmnsn_astnode -dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - switch (astnode.type) { - case DMNSN_AST_NONE: - case DMNSN_AST_INTEGER: - case DMNSN_AST_FLOAT: - case DMNSN_AST_STRING: - do { - ++*astnode.refcount; - } while (*astnode.refcount <= 1); - return astnode; - - case DMNSN_AST_VECTOR: - return dmnsn_vector_promote(astnode, symtable); - - case DMNSN_AST_IDENTIFIER: - { - dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, astnode.ptr); - if (symbol) { - dmnsn_astnode id = *symbol; - id.location = astnode.location; - return dmnsn_eval(id, symtable); - } else { - dmnsn_diagnostic(astnode.location, "unbound identifier '%s'", - (const char *)astnode.ptr); - dmnsn_astnode error = dmnsn_new_astnode(DMNSN_AST_NONE); - ++*error.refcount; - return error; - } - } - - case DMNSN_AST_PI: - case DMNSN_AST_TRUE: - case DMNSN_AST_FALSE: - case DMNSN_AST_X: - case DMNSN_AST_Y: - case DMNSN_AST_Z: - case DMNSN_AST_T: - return dmnsn_eval_zeroary(astnode, symtable); - - case DMNSN_AST_DOT_X: - case DMNSN_AST_DOT_Y: - case DMNSN_AST_DOT_Z: - case DMNSN_AST_DOT_T: - case DMNSN_AST_DOT_TRANSMIT: - case DMNSN_AST_NEGATE: - case DMNSN_AST_NOT: - case DMNSN_AST_ABS: - case DMNSN_AST_ACOS: - case DMNSN_AST_ACOSH: - case DMNSN_AST_ASC: - case DMNSN_AST_ASIN: - case DMNSN_AST_ASINH: - case DMNSN_AST_ATAN: - case DMNSN_AST_ATANH: - case DMNSN_AST_CEIL: - case DMNSN_AST_COS: - case DMNSN_AST_COSH: - case DMNSN_AST_DEGREES: - case DMNSN_AST_EXP: - case DMNSN_AST_FLOOR: - case DMNSN_AST_INT: - case DMNSN_AST_LN: - case DMNSN_AST_LOG: - case DMNSN_AST_RADIANS: - case DMNSN_AST_SIN: - case DMNSN_AST_SINH: - case DMNSN_AST_SQRT: - case DMNSN_AST_STRLEN: - case DMNSN_AST_TAN: - case DMNSN_AST_TANH: - case DMNSN_AST_VAL: - case DMNSN_AST_VLENGTH: - case DMNSN_AST_VNORMALIZE: - return dmnsn_eval_unary(astnode, symtable); - - case DMNSN_AST_ADD: - case DMNSN_AST_SUB: - case DMNSN_AST_MUL: - case DMNSN_AST_DIV: - case DMNSN_AST_EQUAL: - case DMNSN_AST_NOT_EQUAL: - case DMNSN_AST_LESS: - case DMNSN_AST_LESS_EQUAL: - case DMNSN_AST_GREATER: - case DMNSN_AST_GREATER_EQUAL: - case DMNSN_AST_AND: - case DMNSN_AST_OR: - case DMNSN_AST_ATAN2: - case DMNSN_AST_INT_DIV: - case DMNSN_AST_MAX: - case DMNSN_AST_MIN: - case DMNSN_AST_MOD: - case DMNSN_AST_POW: - case DMNSN_AST_STRCMP: - case DMNSN_AST_VAXIS_ROTATE: - case DMNSN_AST_VCROSS: - case DMNSN_AST_VDOT: - case DMNSN_AST_VROTATE: - return dmnsn_eval_binary(astnode, symtable); - - case DMNSN_AST_TERNARY: - return dmnsn_eval_ternary(astnode, symtable); - - default: - dmnsn_diagnostic(astnode.location, - "expected arithmetic expression; found %s", - dmnsn_astnode_string(astnode.type)); - dmnsn_astnode error = dmnsn_new_astnode(DMNSN_AST_NONE); - ++*error.refcount; - return error; - } - - return astnode; -} - -dmnsn_astnode -dmnsn_eval_scalar(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - dmnsn_astnode ret = dmnsn_eval(astnode, symtable); - if (ret.type != DMNSN_AST_INTEGER && ret.type != DMNSN_AST_FLOAT - && ret.type != DMNSN_AST_NONE) - { - dmnsn_diagnostic(ret.location, "expected %s or %s; found %s", - dmnsn_astnode_string(DMNSN_AST_INTEGER), - dmnsn_astnode_string(DMNSN_AST_FLOAT), - dmnsn_astnode_string(ret.type)); - dmnsn_delete_astnode(ret); - ret = dmnsn_new_astnode(DMNSN_AST_NONE); - } - return ret; -} - -dmnsn_astnode -dmnsn_eval_vector(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) -{ - dmnsn_astnode eval = dmnsn_eval(astnode, symtable); - dmnsn_astnode ret = dmnsn_vector_promote(eval, symtable); - dmnsn_delete_astnode(eval); - return ret; -} - -static void -dmnsn_print_astnode(FILE *file, dmnsn_astnode astnode) -{ - long ivalue; - double dvalue; - const char *svalue; - - switch (astnode.type) { - case DMNSN_AST_INTEGER: - ivalue = *(long *)astnode.ptr; - fprintf(file, "(%s %ld)", dmnsn_astnode_string(astnode.type), ivalue); - break; - - case DMNSN_AST_FLOAT: - dvalue = *(double *)astnode.ptr; - /* Don't print -0 */ - if (dvalue == 0.0) - fprintf(file, "(%s 0)", dmnsn_astnode_string(astnode.type)); - else - fprintf(file, "(%s %g)", dmnsn_astnode_string(astnode.type), dvalue); - break; - - case DMNSN_AST_STRING: - svalue = astnode.ptr; - fprintf(file, "(%s \"%s\")", dmnsn_astnode_string(astnode.type), svalue); - break; - - default: - fprintf(file, "%s", dmnsn_astnode_string(astnode.type)); - } -} - -static void -dmnsn_print_astree(FILE *file, dmnsn_astnode astnode) -{ - if (astnode.children && dmnsn_array_size(astnode.children) > 0) { - fprintf(file, "("); - dmnsn_print_astnode(file, astnode); - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, child, astnode.children) { - fprintf(file, " "); - dmnsn_print_astree(file, *child); - } - fprintf(file, ")"); - } else { - dmnsn_print_astnode(file, astnode); - } -} - -void -dmnsn_print_astree_sexpr(FILE *file, const dmnsn_astree *astree) -{ - if (dmnsn_array_size(astree) == 0) { - fprintf(file, "()"); - } else { - fprintf(file, "("); - dmnsn_astnode *astnode = dmnsn_array_first(astree); - dmnsn_print_astree(file, *astnode); - - for (++astnode; - astnode <= (dmnsn_astnode *)dmnsn_array_last(astree); - ++astnode) - { - fprintf(file, " "); - dmnsn_print_astree(file, *astnode); - } - - fprintf(file, ")"); - } - - fprintf(file, "\n"); -} diff --git a/dimension/parse.h b/dimension/parse.h deleted file mode 100644 index a357324..0000000 --- a/dimension/parse.h +++ /dev/null @@ -1,284 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#ifndef PARSE_H -#define PARSE_H - -#include "dimension.h" - -/* - * Abstract syntax tree - */ - -/* Abstract syntax tree node types */ -typedef enum { - DMNSN_AST_NONE, - - DMNSN_AST_GLOBAL_SETTINGS, - DMNSN_AST_ADC_BAILOUT, - DMNSN_AST_ASSUMED_GAMMA, - DMNSN_AST_CHARSET, - DMNSN_AST_ASCII, - DMNSN_AST_UTF8, - DMNSN_AST_SYS, - DMNSN_AST_MAX_TRACE_LEVEL, - DMNSN_AST_MAX_INTERSECTIONS, - - DMNSN_AST_BACKGROUND, - DMNSN_AST_SKY_SPHERE, - - DMNSN_AST_CAMERA, - DMNSN_AST_PERSPECTIVE, - DMNSN_AST_LOCATION, - DMNSN_AST_RIGHT, - DMNSN_AST_UP, - DMNSN_AST_SKY, - DMNSN_AST_ANGLE, - DMNSN_AST_LOOK_AT, - DMNSN_AST_DIRECTION, - - DMNSN_AST_OBJECT, - DMNSN_AST_BOX, - DMNSN_AST_CONE, - DMNSN_AST_CYLINDER, - DMNSN_AST_DIFFERENCE, - DMNSN_AST_INTERSECTION, - DMNSN_AST_LIGHT_SOURCE, - DMNSN_AST_MERGE, - DMNSN_AST_PLANE, - DMNSN_AST_SPHERE, - DMNSN_AST_TORUS, - DMNSN_AST_UNION, - - DMNSN_AST_OBJECT_MODIFIERS, - DMNSN_AST_STURM, - - DMNSN_AST_PATTERN, - DMNSN_AST_CHECKER, - DMNSN_AST_GRADIENT, - - DMNSN_AST_TEXTURE, - - DMNSN_AST_PIGMENT, - DMNSN_AST_PIGMENT_MODIFIERS, - DMNSN_AST_COLOR_LIST, - DMNSN_AST_COLOR_MAP, - DMNSN_AST_COLOR_MAP_ENTRY, - DMNSN_AST_PIGMENT_LIST, - DMNSN_AST_PIGMENT_MAP, - DMNSN_AST_PIGMENT_MAP_ENTRY, - DMNSN_AST_QUICK_COLOR, - DMNSN_AST_IMAGE_MAP, - DMNSN_AST_PNG, - - DMNSN_AST_FINISH, - DMNSN_AST_AMBIENT, - DMNSN_AST_DIFFUSE, - DMNSN_AST_PHONG, - DMNSN_AST_PHONG_SIZE, - - DMNSN_AST_REFLECTION, - DMNSN_AST_REFLECTION_ITEMS, - DMNSN_AST_FALLOFF, - - DMNSN_AST_INTERIOR, - DMNSN_AST_IOR, - - DMNSN_AST_TRANSFORMATION, - DMNSN_AST_ROTATION, - DMNSN_AST_SCALE, - DMNSN_AST_TRANSLATION, - DMNSN_AST_MATRIX, - DMNSN_AST_INVERSE, - - DMNSN_AST_FLOAT, - DMNSN_AST_INTEGER, - - DMNSN_AST_VECTOR, - - DMNSN_AST_ADD, - DMNSN_AST_SUB, - DMNSN_AST_MUL, - DMNSN_AST_DIV, - - DMNSN_AST_NEGATE, - DMNSN_AST_DOT_X, - DMNSN_AST_DOT_Y, - DMNSN_AST_DOT_Z, - DMNSN_AST_DOT_T, - DMNSN_AST_DOT_TRANSMIT, - - DMNSN_AST_EQUAL, - DMNSN_AST_NOT_EQUAL, - DMNSN_AST_LESS, - DMNSN_AST_LESS_EQUAL, - DMNSN_AST_GREATER, - DMNSN_AST_GREATER_EQUAL, - DMNSN_AST_AND, - DMNSN_AST_OR, - DMNSN_AST_NOT, - DMNSN_AST_TERNARY, - - DMNSN_AST_ABS, - DMNSN_AST_ACOS, - DMNSN_AST_ACOSH, - DMNSN_AST_ASC, - DMNSN_AST_ASIN, - DMNSN_AST_ASINH, - DMNSN_AST_ATAN, - DMNSN_AST_ATAN2, - DMNSN_AST_ATANH, - DMNSN_AST_CEIL, - DMNSN_AST_COS, - DMNSN_AST_COSH, - DMNSN_AST_DEGREES, - DMNSN_AST_INT_DIV, - DMNSN_AST_EXP, - DMNSN_AST_FLOOR, - DMNSN_AST_INT, - DMNSN_AST_LN, - DMNSN_AST_LOG, - DMNSN_AST_MAX, - DMNSN_AST_MIN, - DMNSN_AST_MOD, - DMNSN_AST_POW, - DMNSN_AST_RADIANS, - DMNSN_AST_SIN, - DMNSN_AST_SINH, - DMNSN_AST_SQRT, - DMNSN_AST_STRCMP, - DMNSN_AST_STRLEN, - DMNSN_AST_TAN, - DMNSN_AST_TANH, - DMNSN_AST_VAL, - DMNSN_AST_VAXIS_ROTATE, - DMNSN_AST_VCROSS, - DMNSN_AST_VDOT, - DMNSN_AST_VLENGTH, - DMNSN_AST_VNORMALIZE, - DMNSN_AST_VROTATE, - - DMNSN_AST_PI, - DMNSN_AST_TRUE, - DMNSN_AST_FALSE, - DMNSN_AST_X, - DMNSN_AST_Y, - DMNSN_AST_Z, - DMNSN_AST_T, - - DMNSN_AST_IDENTIFIER, - - DMNSN_AST_STRING, - - DMNSN_AST_ARRAY, - - DMNSN_AST_MACRO -} dmnsn_astnode_type; - -typedef struct dmnsn_astnode dmnsn_astnode; - -typedef struct dmnsn_parse_location { - const char *first_filename, *last_filename; - int first_line, last_line; - int first_column, last_column; - - struct dmnsn_parse_location *parent; -} dmnsn_parse_location; - -/* Abstract syntax tree node (a dmnsn_array* of these is an AST) */ -struct dmnsn_astnode { - dmnsn_astnode_type type; - - /* Child nodes */ - dmnsn_array *children; - - /* Generic data pointer */ - void *ptr; - dmnsn_free_fn *free_fn; - - /* Reference count */ - unsigned int *refcount; - - /* File name, and line and column numbers from source code */ - dmnsn_parse_location location; -}; - -typedef dmnsn_array dmnsn_astree; - -dmnsn_astnode dmnsn_new_ast_array(void); -dmnsn_astnode dmnsn_new_ast_integer(long value); -dmnsn_astnode dmnsn_new_ast_float(double value); -dmnsn_astnode dmnsn_new_ast_ivector(long x, long y, long z, long f, long t); -dmnsn_astnode dmnsn_new_ast_vector(double x, double y, double z, - double f, double t); -dmnsn_astnode dmnsn_new_ast_string(const char *value); - -void dmnsn_delete_astnode(dmnsn_astnode astnode); -void dmnsn_delete_astree(dmnsn_astree *astree); - -/* Print an S-expression of the abstract syntax tree to `file' */ -void dmnsn_print_astree_sexpr(FILE *file, const dmnsn_astree *astree); - -/* Returns a readable name for an astnode type (ex. DMNSN_AST_FLOAT -> float) */ -const char *dmnsn_astnode_string(dmnsn_astnode_type astnode_type); - -/* - * Symbol table - */ - -typedef dmnsn_array dmnsn_symbol_table; - -dmnsn_symbol_table *dmnsn_new_symbol_table(void); - -void dmnsn_delete_symbol_table(dmnsn_symbol_table *symtable); - -void dmnsn_push_scope(dmnsn_symbol_table *symtable); -void dmnsn_pop_scope(dmnsn_symbol_table *symtable); - -void dmnsn_local_symbol(dmnsn_symbol_table *symtable, - const char *id, dmnsn_astnode value); -void dmnsn_declare_symbol(dmnsn_symbol_table *symtable, - const char *id, dmnsn_astnode value); -void dmnsn_undef_symbol(dmnsn_symbol_table *symtable, const char *id); - -dmnsn_astnode *dmnsn_find_symbol(dmnsn_symbol_table *symtable, const char *id); - -/* Evaluate an arithmetic expression */ -dmnsn_astnode dmnsn_eval(dmnsn_astnode astnode, dmnsn_symbol_table *symtable); -dmnsn_astnode dmnsn_eval_scalar(dmnsn_astnode astnode, - dmnsn_symbol_table *symtable); -dmnsn_astnode dmnsn_eval_vector(dmnsn_astnode astnode, - dmnsn_symbol_table *symtable); - - -/* - * The workhorse -- parse a file - */ -dmnsn_astree *dmnsn_parse(FILE *file, dmnsn_symbol_table *symtable); -dmnsn_astree *dmnsn_parse_string(const char *str, dmnsn_symbol_table *symtable); - -/* - * Parser internals - */ -typedef union dmnsn_parse_item { - char *value; - dmnsn_astnode astnode; -} dmnsn_parse_item; - -#endif /* PARSE_H */ diff --git a/dimension/platform.c b/dimension/platform.c deleted file mode 100644 index fec9159..0000000 --- a/dimension/platform.c +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "platform.h" -#if HAVE_UNISTD_H - #include <unistd.h> -#endif -#if DMNSN_TIOCGWINSZ - #include <sys/ioctl.h> -#endif - -unsigned int -dmnsn_terminal_width(void) -{ -#if DMNSN_TIOCGWINSZ - struct winsize ws; - unsigned int width = 80; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) { - width = ws.ws_col; - } - return width; -#else - return 80; -#endif -} diff --git a/dimension/platform.h b/dimension/platform.h deleted file mode 100644 index d4dacf5..0000000 --- a/dimension/platform.h +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#ifndef PLATFORM_H -#define PLATFORM_H - -#include "dimension.h" - -/** - * Get the width of the terminal. - * @return The width (in characters) of the terminal, defaulting to 80. - */ -unsigned int dmnsn_terminal_width(void); - -#endif /* PLATFORM_H */ diff --git a/dimension/progressbar.c b/dimension/progressbar.c deleted file mode 100644 index b5d8792..0000000 --- a/dimension/progressbar.c +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "progressbar.h" -#include "platform.h" -#include <stdarg.h> -#include <stdio.h> - -void -dmnsn_progressbar(const char *format, const dmnsn_progress *progress, ...) -{ - va_list ap; - va_start(ap, progress); - - int len = vprintf(format, ap) + 1; - if (len < 1) - len = 1; - printf(" "); - - va_end(ap); - - fflush(stdout); - - /* Try to fill the terminal with the progress bar */ - unsigned int width = dmnsn_terminal_width(); - unsigned int increments = width - (len % width); - for (unsigned int i = 0; i < increments; ++i) { - dmnsn_wait_progress(progress, ((double)(i + 1))/increments); - - printf("."); - fflush(stdout); - } - printf("\n"); - fflush(stdout); -} diff --git a/dimension/progressbar.h b/dimension/progressbar.h deleted file mode 100644 index 7989b1c..0000000 --- a/dimension/progressbar.h +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#ifndef PROGRESSBAR_H -#define PROGRESSBAR_H - -#include "dimension.h" -#include "utility.h" /* For DMNSN_PRINTF_WARN */ - -/* Print a progress bar of the progress of `progress' */ -void dmnsn_progressbar(const char *format, const dmnsn_progress *progress, - ...) - DMNSN_PRINTF_WARN(1, 3); - -#endif /* PROGRESSBAR_H */ diff --git a/dimension/realize.c b/dimension/realize.c deleted file mode 100644 index c9a507d..0000000 --- a/dimension/realize.c +++ /dev/null @@ -1,1450 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "realize.h" -#include "parse.h" -#include "utility.h" -#include <math.h> -#include <fenv.h> -#include <stdio.h> -#include <stdbool.h> - -static long -dmnsn_realize_integer(dmnsn_astnode astnode) -{ - switch (astnode.type) { - case DMNSN_AST_INTEGER: - return *(long *)astnode.ptr; - case DMNSN_AST_FLOAT: - { - feclearexcept(FE_ALL_EXCEPT); - long ret = lrint(*(double *)astnode.ptr); - if (fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)) - dmnsn_error("Float out of range of integer."); - return ret; - } - - default: - dmnsn_assert(false, "Invalid integer."); - return 0; /* Silence compiler warning */ - } -} - -static double -dmnsn_realize_float(dmnsn_astnode astnode) -{ - switch (astnode.type) { - case DMNSN_AST_FLOAT: - return *(double *)astnode.ptr; - case DMNSN_AST_INTEGER: - return *(long *)astnode.ptr; - - default: - dmnsn_assert(false, "Invalid float."); - return 0; /* Silence compiler warning */ - } -} - -/* dmnsn_realize_string is an API function, so call this dmnsn_realize_str */ -static const char* -dmnsn_realize_str(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_STRING, "Expected a string."); - return astnode.ptr; -} - -static dmnsn_vector -dmnsn_realize_vector(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_VECTOR, "Expected a vector."); - - dmnsn_astnode xnode, ynode, znode; - dmnsn_array_get(astnode.children, 0, &xnode); - dmnsn_array_get(astnode.children, 1, &ynode); - dmnsn_array_get(astnode.children, 2, &znode); - - double x = dmnsn_realize_float(xnode), - y = dmnsn_realize_float(ynode), - z = dmnsn_realize_float(znode); - - return dmnsn_new_vector(x, y, z); -} - -static dmnsn_color -dmnsn_realize_color(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_VECTOR, "Expected a vector."); - - dmnsn_astnode rnode, gnode, bnode, fnode, tnode; - dmnsn_array_get(astnode.children, 0, &rnode); - dmnsn_array_get(astnode.children, 1, &gnode); - dmnsn_array_get(astnode.children, 2, &bnode); - dmnsn_array_get(astnode.children, 3, &fnode); - dmnsn_array_get(astnode.children, 4, &tnode); - - return dmnsn_new_color5(dmnsn_realize_float(rnode), - dmnsn_realize_float(gnode), - dmnsn_realize_float(bnode), - dmnsn_realize_float(fnode), - dmnsn_realize_float(tnode)); -} - -static dmnsn_matrix -dmnsn_realize_translation(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_TRANSLATION, - "Expected a translation."); - - dmnsn_astnode trans_node; - dmnsn_array_get(astnode.children, 0, &trans_node); - dmnsn_vector trans = dmnsn_realize_vector(trans_node); - - return dmnsn_translation_matrix(trans); -} - -static dmnsn_matrix -dmnsn_realize_scale(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_SCALE, "Expected a scale."); - - dmnsn_astnode scale_node; - dmnsn_array_get(astnode.children, 0, &scale_node); - dmnsn_vector scale = dmnsn_realize_vector(scale_node); - - return dmnsn_scale_matrix(scale); -} - -static dmnsn_matrix -dmnsn_realize_rotation(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_ROTATION, "Expected a rotation."); - - dmnsn_astnode angle_node; - dmnsn_array_get(astnode.children, 0, &angle_node); - - dmnsn_vector angle = dmnsn_vector_mul( - dmnsn_radians(1.0), - dmnsn_realize_vector(angle_node) - ); - - dmnsn_matrix trans = dmnsn_rotation_matrix( - dmnsn_new_vector(angle.x, 0.0, 0.0) - ); - trans = dmnsn_matrix_mul( - dmnsn_rotation_matrix(dmnsn_new_vector(0.0, angle.y, 0.0)), - trans - ); - trans = dmnsn_matrix_mul( - dmnsn_rotation_matrix(dmnsn_new_vector(0.0, 0.0, angle.z)), - trans - ); - - return trans; -} - -static dmnsn_matrix -dmnsn_realize_matrix(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_MATRIX, "Expected a matrix."); - - dmnsn_astnode *children = dmnsn_array_first(astnode.children); - dmnsn_matrix trans; - - trans.n[0][0] = dmnsn_realize_float(children[0]); - trans.n[0][1] = dmnsn_realize_float(children[1]); - trans.n[0][2] = dmnsn_realize_float(children[2]); - trans.n[0][3] = dmnsn_realize_float(children[9]); - - trans.n[1][0] = dmnsn_realize_float(children[3]); - trans.n[1][1] = dmnsn_realize_float(children[4]); - trans.n[1][2] = dmnsn_realize_float(children[5]); - trans.n[1][3] = dmnsn_realize_float(children[10]); - - trans.n[2][0] = dmnsn_realize_float(children[6]); - trans.n[2][1] = dmnsn_realize_float(children[7]); - trans.n[2][2] = dmnsn_realize_float(children[8]); - trans.n[2][3] = dmnsn_realize_float(children[11]); - - return trans; -} - -static dmnsn_matrix -dmnsn_realize_transformation(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_TRANSFORMATION, - "Expected a transformation."); - - dmnsn_matrix trans = dmnsn_identity_matrix(); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, child, astnode.children) { - switch (child->type) { - case DMNSN_AST_TRANSLATION: - trans = dmnsn_matrix_mul(trans, dmnsn_realize_translation(*child)); - break; - case DMNSN_AST_SCALE: - trans = dmnsn_matrix_mul(trans, dmnsn_realize_scale(*child)); - break; - case DMNSN_AST_ROTATION: - trans = dmnsn_matrix_mul(trans, dmnsn_realize_rotation(*child)); - break; - case DMNSN_AST_MATRIX: - trans = dmnsn_matrix_mul(trans, dmnsn_realize_matrix(*child)); - break; - case DMNSN_AST_INVERSE: - trans = dmnsn_matrix_inverse(trans); - break; - case DMNSN_AST_TRANSFORMATION: - trans = dmnsn_matrix_mul(trans, dmnsn_realize_transformation(*child)); - break; - - default: - dmnsn_assert(false, "Invalid transformation type."); - break; - } - } - - return trans; -} - -static void -dmnsn_realize_global_settings(dmnsn_astnode astnode, dmnsn_scene *scene) -{ - dmnsn_assert(astnode.type == DMNSN_AST_GLOBAL_SETTINGS, - "Expected global settings."); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { - dmnsn_astnode child; - - switch (item->type) { - case DMNSN_AST_ADC_BAILOUT: - dmnsn_array_get(item->children, 0, &child); - scene->adc_bailout = dmnsn_realize_float(child); - break; - - case DMNSN_AST_AMBIENT: - dmnsn_array_get(item->children, 0, &child); - scene->ambient = dmnsn_realize_color(child); - scene->ambient.filter = 0.0; - scene->ambient.trans = 0.0; - break; - - case DMNSN_AST_MAX_TRACE_LEVEL: - dmnsn_array_get(item->children, 0, &child); - scene->reclimit = dmnsn_realize_integer(child); - break; - - case DMNSN_AST_ASSUMED_GAMMA: - case DMNSN_AST_CHARSET: - case DMNSN_AST_MAX_INTERSECTIONS: - /* Ignored settings */ - break; - - default: - dmnsn_assert(false, "Invalid global settings item."); - } - } -} - -static dmnsn_pigment *dmnsn_realize_pigment(dmnsn_astnode astnode); - -static dmnsn_sky_sphere * -dmnsn_realize_sky_sphere(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_SKY_SPHERE, "Expected a sky sphere."); - - dmnsn_sky_sphere *sky_sphere = dmnsn_new_sky_sphere(); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { - switch (item->type) { - case DMNSN_AST_PIGMENT: - { - dmnsn_pigment *pigment = dmnsn_realize_pigment(*item); - dmnsn_array_push(sky_sphere->pigments, &pigment); - break; - } - - case DMNSN_AST_TRANSFORMATION: - sky_sphere->trans = dmnsn_matrix_mul( - dmnsn_realize_transformation(*item), - sky_sphere->trans - ); - break; - - default: - dmnsn_assert(false, "Invalid sky sphere item."); - } - } - - return sky_sphere; -} - -static dmnsn_camera * -dmnsn_realize_camera(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_CAMERA, "Expected a camera."); - - dmnsn_astnode_type camera_type = DMNSN_AST_PERSPECTIVE; - dmnsn_vector location = dmnsn_new_vector(0.0, 0.0, 0.0); - dmnsn_vector direction = dmnsn_new_vector(0.0, 0.0, 1.0); - dmnsn_vector right = dmnsn_new_vector(4.0/3.0, 0.0, 0.0); - dmnsn_vector up = dmnsn_new_vector(0.0, 1.0, 0.0); - dmnsn_vector sky = dmnsn_new_vector(0.0, 1.0, 0.0); - dmnsn_matrix trans = dmnsn_identity_matrix(); - - dmnsn_camera *camera = NULL; - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { - dmnsn_astnode child; - - switch (item->type) { - /* Camera types */ - case DMNSN_AST_PERSPECTIVE: - camera_type = item->type; - break; - - /* Camera vectors */ - case DMNSN_AST_LOCATION: - dmnsn_array_get(item->children, 0, &child); - location = dmnsn_realize_vector(child); - break; - case DMNSN_AST_RIGHT: - dmnsn_array_get(item->children, 0, &child); - right = dmnsn_realize_vector(child); - break; - case DMNSN_AST_UP: - dmnsn_array_get(item->children, 0, &child); - right = dmnsn_realize_vector(child); - break; - case DMNSN_AST_SKY: - dmnsn_array_get(item->children, 0, &child); - sky = dmnsn_realize_vector(child); - break; - case DMNSN_AST_DIRECTION: - dmnsn_array_get(item->children, 0, &child); - direction = dmnsn_realize_vector(child); - break; - - /* Camera modifiers */ - - case DMNSN_AST_LOOK_AT: - { - dmnsn_array_get(item->children, 0, &child); - dmnsn_vector look_at = dmnsn_realize_vector(child); - - /* Line the camera up with the sky */ - - dmnsn_matrix sky1 = dmnsn_rotation_matrix( - dmnsn_vector_mul( - dmnsn_vector_axis_angle(up, sky, direction), - dmnsn_vector_normalize(direction) - ) - ); - up = dmnsn_transform_vector(sky1, up); - right = dmnsn_transform_vector(sky1, right); - - dmnsn_matrix sky2 = dmnsn_rotation_matrix( - dmnsn_vector_mul( - dmnsn_vector_axis_angle(up, sky, right), - dmnsn_vector_normalize(right) - ) - ); - up = dmnsn_transform_vector(sky2, up); - direction = dmnsn_transform_vector(sky2, direction); - - /* Line up the camera with the look_at */ - - look_at = dmnsn_vector_sub(look_at, location); - dmnsn_matrix look_at1 = dmnsn_rotation_matrix( - dmnsn_vector_mul( - dmnsn_vector_axis_angle(direction, look_at, up), - dmnsn_vector_normalize(up) - ) - ); - right = dmnsn_transform_vector(look_at1, right); - direction = dmnsn_transform_vector(look_at1, direction); - - dmnsn_matrix look_at2 = dmnsn_rotation_matrix( - dmnsn_vector_mul( - dmnsn_vector_axis_angle(direction, look_at, right), - dmnsn_vector_normalize(right) - ) - ); - up = dmnsn_transform_vector(look_at2, up); - direction = dmnsn_transform_vector(look_at2, direction); - - break; - } - - case DMNSN_AST_ANGLE: - { - dmnsn_array_get(item->children, 0, &child); - double angle = dmnsn_radians(dmnsn_realize_float(child)); - direction = dmnsn_vector_mul( - 0.5*dmnsn_vector_norm(right)/tan(angle/2.0), - dmnsn_vector_normalize(direction) - ); - break; - } - - /* Transformations */ - case DMNSN_AST_TRANSFORMATION: - trans = dmnsn_matrix_mul(dmnsn_realize_transformation(*item), trans); - break; - - default: - dmnsn_assert(false, "Invalid camera item."); - break; - } - } - - switch (camera_type) { - case DMNSN_AST_PERSPECTIVE: - { - /* These multiplications are in right-to-left order so that user - transformations happen after camera alignment */ - - trans = dmnsn_matrix_mul(trans, dmnsn_translation_matrix(location)); - - /* Align y with `up' */ - - dmnsn_matrix align = dmnsn_rotation_matrix( - dmnsn_vector_mul( - dmnsn_vector_axis_angle(dmnsn_y, up, dmnsn_z), - dmnsn_z - ) - ); - - dmnsn_vector x = dmnsn_transform_vector(align, dmnsn_x); - dmnsn_vector y = dmnsn_transform_vector(align, dmnsn_y); - - align = dmnsn_matrix_mul( - dmnsn_rotation_matrix( - dmnsn_vector_mul( - dmnsn_vector_axis_angle(y, up, x), - x - ) - ), - align - ); - - /* Align x with `right' */ - - align = dmnsn_matrix_mul( - dmnsn_rotation_matrix( - dmnsn_vector_mul( - dmnsn_vector_axis_angle(x, right, up), - dmnsn_vector_normalize(up) - ) - ), - align - ); - - trans = dmnsn_matrix_mul(trans, align); - - /* Scale the camera with `up', `right', and `direction' */ - trans = dmnsn_matrix_mul( - trans, - dmnsn_scale_matrix( - dmnsn_new_vector( - dmnsn_vector_norm(right), - dmnsn_vector_norm(up), - dmnsn_vector_norm(direction) - ) - ) - ); - - camera = dmnsn_new_perspective_camera(); - break; - } - - default: - dmnsn_assert(false, "Unsupported camera type."); - } - - camera->trans = trans; - return camera; -} - -static dmnsn_pattern * -dmnsn_realize_pattern(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_PATTERN, "Expected a pattern."); - - dmnsn_astnode type; - dmnsn_array_get(astnode.children, 0, &type); - - dmnsn_pattern *pattern = NULL; - - switch (type.type) { - case DMNSN_AST_CHECKER: - pattern = dmnsn_new_checker_pattern(); - break; - case DMNSN_AST_GRADIENT: - { - dmnsn_astnode orientation; - dmnsn_array_get(type.children, 0, &orientation); - dmnsn_vector v = dmnsn_realize_vector(orientation); - pattern = dmnsn_new_gradient_pattern(v); - break; - } - - default: - dmnsn_assert(false, "Unexpected pattern type."); - } - - return pattern; -} - -static dmnsn_map * -dmnsn_realize_color_list(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_COLOR_LIST, "Expected a color list."); - - dmnsn_map *color_map = dmnsn_new_color_map(); - - double n = 0.0, i = 1.0/(dmnsn_array_size(astnode.children) - 1); - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) { - dmnsn_color color = dmnsn_realize_color(*entry); - dmnsn_add_map_entry(color_map, n, &color); - n += i; - } - - return color_map; -} - -static dmnsn_map * -dmnsn_realize_color_map(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_COLOR_MAP, "Expected a color_map."); - - dmnsn_map *color_map = dmnsn_new_color_map(); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) { - dmnsn_assert(entry->type == DMNSN_AST_COLOR_MAP_ENTRY, - "Expected a color_map entry."); - - dmnsn_astnode n_node, color_node; - dmnsn_array_get(entry->children, 0, &n_node); - dmnsn_array_get(entry->children, 1, &color_node); - - double n = dmnsn_realize_float(n_node); - dmnsn_color color = dmnsn_realize_color(color_node); - - dmnsn_add_map_entry(color_map, n, &color); - } - - return color_map; -} - -static dmnsn_map * -dmnsn_realize_pigment_list(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_LIST, - "Expected a pigment list."); - - dmnsn_map *pigment_map = dmnsn_new_pigment_map(); - - double n = 0.0, i = 1.0/(dmnsn_array_size(astnode.children) - 1); - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) { - dmnsn_pigment *pigment = dmnsn_realize_pigment(*entry); - dmnsn_add_map_entry(pigment_map, n, &pigment); - n += i; - } - - return pigment_map; -} - -static dmnsn_map * -dmnsn_realize_pigment_map(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_MAP, - "Expected a pigment_map."); - - dmnsn_map *pigment_map = dmnsn_new_pigment_map(); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) { - dmnsn_assert(entry->type == DMNSN_AST_PIGMENT_MAP_ENTRY, - "Expected a pigment_map entry."); - - dmnsn_astnode n_node, pigment_node; - dmnsn_array_get(entry->children, 0, &n_node); - dmnsn_array_get(entry->children, 1, &pigment_node); - - double n = dmnsn_realize_float(n_node); - dmnsn_pigment *pigment = dmnsn_realize_pigment(pigment_node); - - dmnsn_add_map_entry(pigment_map, n, &pigment); - } - - return pigment_map; -} - -static dmnsn_pigment * -dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers) -{ - dmnsn_assert(modifiers.type == DMNSN_AST_PIGMENT_MODIFIERS, - "Expected pigment modifiers"); - - dmnsn_pattern *pattern = dmnsn_realize_pattern(type); - dmnsn_map *color_map = NULL, *pigment_map = NULL; - - /* Set up the map */ - DMNSN_ARRAY_FOREACH_REVERSE (dmnsn_astnode *, modifier, modifiers.children) { - switch (modifier->type) { - case DMNSN_AST_COLOR_LIST: - color_map = dmnsn_realize_color_list(*modifier); - break; - case DMNSN_AST_COLOR_MAP: - color_map = dmnsn_realize_color_map(*modifier); - break; - - case DMNSN_AST_PIGMENT_LIST: - pigment_map = dmnsn_realize_pigment_list(*modifier); - break; - case DMNSN_AST_PIGMENT_MAP: - pigment_map = dmnsn_realize_pigment_map(*modifier); - break; - - default: - break; - } - - if (color_map || pigment_map) - break; - } - - /* Now add the default values */ - - dmnsn_astnode pattern_type; - dmnsn_array_get(type.children, 0, &pattern_type); - - switch (pattern_type.type) { - case DMNSN_AST_CHECKER: - /* Default checker pattern is blue and green */ - if (!color_map && !pigment_map) { - color_map = dmnsn_new_color_map(); - if (dmnsn_map_size(color_map) < 1) - dmnsn_add_map_entry(color_map, 0.0, &dmnsn_blue); - if (dmnsn_map_size(color_map) < 2) - dmnsn_add_map_entry(color_map, 1.0, &dmnsn_green); - } - break; - - default: - /* Default map is grayscale */ - if (!color_map && !pigment_map) { - color_map = dmnsn_new_color_map(); - dmnsn_add_map_entry(color_map, 0.0, &dmnsn_black); - dmnsn_add_map_entry(color_map, 1.0, &dmnsn_white); - } - break; - } - - dmnsn_pigment *pigment = NULL; - if (color_map) { - pigment = dmnsn_new_color_map_pigment(pattern, color_map); - } else if (pigment_map) { - pigment = dmnsn_new_pigment_map_pigment(pattern, pigment_map); - } else { - dmnsn_assert(false, "No appropriate map constructed."); - } - return pigment; -} - -static void -dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment) -{ - dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_MODIFIERS, - "Expected pigment modifiers."); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, modifier, astnode.children) { - switch (modifier->type) { - case DMNSN_AST_TRANSFORMATION: - pigment->trans = dmnsn_matrix_mul( - dmnsn_realize_transformation(*modifier), - pigment->trans - ); - break; - - case DMNSN_AST_QUICK_COLOR: - { - dmnsn_astnode quick_color; - dmnsn_array_get(modifier->children, 0, &quick_color); - pigment->quick_color = dmnsn_realize_color(quick_color); - break; - } - - case DMNSN_AST_COLOR_LIST: - case DMNSN_AST_COLOR_MAP: - case DMNSN_AST_PIGMENT_LIST: - case DMNSN_AST_PIGMENT_MAP: - /* Already handled by dmnsn_realize_pattern_pigment() */ - break; - - default: - dmnsn_assert(false, "Invalid pigment modifier."); - } - } -} - -static dmnsn_pigment * -dmnsn_realize_pigment(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT, "Expected a pigment."); - - dmnsn_pigment *pigment = NULL; - - dmnsn_astnode type_node, modifiers; - dmnsn_array_get(astnode.children, 0, &type_node); - dmnsn_array_get(astnode.children, 1, &modifiers); - - switch (type_node.type) { - case DMNSN_AST_NONE: - break; - - case DMNSN_AST_VECTOR: - { - dmnsn_color color = dmnsn_realize_color(type_node); - pigment = dmnsn_new_solid_pigment(color); - break; - } - - case DMNSN_AST_PATTERN: - { - pigment = dmnsn_realize_pattern_pigment(type_node, modifiers); - break; - } - - case DMNSN_AST_IMAGE_MAP: - { - dmnsn_astnode filetype, strnode; - dmnsn_array_get(type_node.children, 0, &filetype); - dmnsn_array_get(type_node.children, 1, &strnode); - - const char *path = dmnsn_realize_str(strnode); - FILE *file = fopen(path, "rb"); - if (!file) { - dmnsn_error("Couldn't open image file."); - } - - dmnsn_canvas *canvas; - switch (filetype.type) { - case DMNSN_AST_PNG: - canvas = dmnsn_png_read_canvas(file); - if (!canvas) { - dmnsn_error("Invalid PNG file."); - } - pigment = dmnsn_new_canvas_pigment(canvas); - break; - - default: - dmnsn_assert(false, "Invalid image_map type."); - break; - } - break; - } - - default: - dmnsn_assert(false, "Invalid pigment type."); - } - - dmnsn_realize_pigment_modifiers(modifiers, pigment); - - return pigment; -} - -static dmnsn_finish * -dmnsn_realize_reflection(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_REFLECTION, "Expected a reflection."); - - dmnsn_astnode min_node, max_node; - dmnsn_array_get(astnode.children, 0, &min_node); - dmnsn_array_get(astnode.children, 1, &max_node); - - dmnsn_color min = dmnsn_realize_color(min_node); - dmnsn_color max = dmnsn_realize_color(max_node); - - double falloff = 1.0; - - dmnsn_astnode items; - dmnsn_array_get(astnode.children, 2, &items); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, items.children) { - dmnsn_astnode child; - - switch (item->type) { - case DMNSN_AST_FALLOFF: - dmnsn_array_get(item->children, 0, &child); - falloff = dmnsn_realize_float(child); - break; - - default: - dmnsn_assert(false, "Invalid reflection item."); - } - } - - dmnsn_finish *reflection = dmnsn_new_reflective_finish(min, max, falloff); - - return reflection; -} - -static dmnsn_finish * -dmnsn_realize_finish(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_FINISH, "Expected a finish."); - - dmnsn_finish *finish = dmnsn_new_finish(); - - dmnsn_color ambient = dmnsn_black; - bool ambient_set = false; - - double diffuse = 0.0; - bool diffuse_set = false; - - double phong = 0.0; - double phong_size = 40.0; - - dmnsn_finish *reflection = NULL; - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { - dmnsn_astnode child; - - switch (item->type) { - case DMNSN_AST_AMBIENT: - dmnsn_array_get(item->children, 0, &child); - ambient = dmnsn_realize_color(child); - ambient_set = true; - break; - - case DMNSN_AST_DIFFUSE: - dmnsn_array_get(item->children, 0, &child); - diffuse = dmnsn_realize_float(child); - diffuse_set = true; - break; - - case DMNSN_AST_PHONG: - dmnsn_array_get(item->children, 0, &child); - phong = dmnsn_realize_float(child); - break; - case DMNSN_AST_PHONG_SIZE: - dmnsn_array_get(item->children, 0, &child); - phong_size = dmnsn_realize_float(child); - break; - - case DMNSN_AST_REFLECTION: - dmnsn_delete_finish(reflection); - reflection = dmnsn_realize_reflection(*item); - break; - - default: - dmnsn_assert(false, "Invalid finish item."); - } - } - - if (ambient_set) { - finish = dmnsn_new_finish_combination( - dmnsn_new_ambient_finish(ambient), - finish - ); - } - - if (diffuse_set) { - finish = dmnsn_new_finish_combination( - dmnsn_new_diffuse_finish(diffuse), - finish - ); - } - - if (phong) { - finish = dmnsn_new_finish_combination( - dmnsn_new_phong_finish(phong, phong_size), - finish - ); - } - - if (reflection) { - finish = dmnsn_new_finish_combination(reflection, finish); - } - - return finish; -} - -static dmnsn_texture * -dmnsn_realize_texture(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_TEXTURE, "Expected a texture."); - - dmnsn_texture *texture = dmnsn_new_texture(); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { - switch (item->type) { - case DMNSN_AST_PIGMENT: - dmnsn_delete_pigment(texture->pigment); - texture->pigment = dmnsn_realize_pigment(*item); - break; - - case DMNSN_AST_FINISH: - dmnsn_delete_finish(texture->finish); - texture->finish = dmnsn_realize_finish(*item); - break; - - case DMNSN_AST_TRANSFORMATION: - texture->trans = dmnsn_matrix_mul( - dmnsn_realize_transformation(*item), - texture->trans - ); - break; - - default: - dmnsn_assert(false, "Invalid texture item."); - } - } - - return texture; -} - -static dmnsn_interior * -dmnsn_realize_interior(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_INTERIOR, "Expected a texture."); - - dmnsn_interior *interior = dmnsn_new_interior(); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { - dmnsn_astnode child; - - switch (item->type) { - case DMNSN_AST_IOR: - dmnsn_array_get(item->children, 0, &child); - interior->ior = dmnsn_realize_float(child); - break; - - default: - dmnsn_assert(false, "Invalid interior item."); - } - } - - return interior; -} - -static void -dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object) -{ - dmnsn_assert(astnode.type == DMNSN_AST_OBJECT_MODIFIERS, - "Expected object modifiers."); - - /* Save the pre-existing transformations */ - dmnsn_matrix existing_trans = dmnsn_matrix_inverse(object->trans); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, modifier, astnode.children) { - switch (modifier->type) { - case DMNSN_AST_TRANSFORMATION: - object->trans = dmnsn_matrix_mul( - dmnsn_realize_transformation(*modifier), - object->trans - ); - break; - - case DMNSN_AST_TEXTURE: - dmnsn_delete_texture(object->texture); - object->texture = dmnsn_realize_texture(*modifier); - break; - case DMNSN_AST_PIGMENT: - if (!object->texture) - object->texture = dmnsn_new_texture(); - dmnsn_delete_pigment(object->texture->pigment); - object->texture->pigment = dmnsn_realize_pigment(*modifier); - break; - case DMNSN_AST_FINISH: - if (!object->texture) - object->texture = dmnsn_new_texture(); - dmnsn_delete_finish(object->texture->finish); - object->texture->finish = dmnsn_realize_finish(*modifier); - break; - - case DMNSN_AST_INTERIOR: - dmnsn_delete_interior(object->interior); - object->interior = dmnsn_realize_interior(*modifier); - break; - - case DMNSN_AST_STURM: - /* Ignored */ - break; - - default: - dmnsn_assert(false, "Invalid object modifier."); - } - } - - if (object->texture) { - /* Right-multiply to counteract any pre-existing transformations -- this - means, for example, that the transformation that makes a sphere have - radius 2 doesn't scale the texture by a factor of 2 */ - object->texture->trans = dmnsn_matrix_mul( - object->texture->trans, - existing_trans - ); - } -} - -static void -dmnsn_realize_light_source_modifiers(dmnsn_astnode astnode, dmnsn_light *light) -{ - dmnsn_assert(astnode.type == DMNSN_AST_OBJECT_MODIFIERS, - "Expected object modifiers."); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, modifier, astnode.children) { - switch (modifier->type) { - case DMNSN_AST_TRANSFORMATION: - light->x0 = dmnsn_transform_vector( - dmnsn_realize_transformation(*modifier), - light->x0 - ); - break; - - case DMNSN_AST_TEXTURE: - case DMNSN_AST_PIGMENT: - case DMNSN_AST_FINISH: - case DMNSN_AST_INTERIOR: - /* Ignore other object modifiers */ - break; - - default: - dmnsn_assert(false, "Invalid object modifier."); - } - } -} - -static dmnsn_light * -dmnsn_realize_light_source(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_LIGHT_SOURCE, - "Expected a light source."); - - dmnsn_astnode point, color_node; - dmnsn_array_get(astnode.children, 0, &point); - dmnsn_array_get(astnode.children, 1, &color_node); - - dmnsn_vector x0 = dmnsn_realize_vector(point); - dmnsn_color color = dmnsn_realize_color(color_node); - - dmnsn_light *light = dmnsn_new_point_light(x0, color); - - dmnsn_astnode modifiers; - dmnsn_array_get(astnode.children, 2, &modifiers); - dmnsn_realize_light_source_modifiers(modifiers, light); - - return light; -} - -static dmnsn_object *dmnsn_realize_object(dmnsn_astnode astnode, - dmnsn_array *lights); - -static dmnsn_object * -dmnsn_realize_box(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_BOX, "Expected a box."); - - dmnsn_astnode corner1, corner2; - dmnsn_array_get(astnode.children, 0, &corner1); - dmnsn_array_get(astnode.children, 1, &corner2); - - dmnsn_vector x1 = dmnsn_realize_vector(corner1), - x2 = dmnsn_realize_vector(corner2); - - dmnsn_object *box = dmnsn_new_cube(); - - box->trans = dmnsn_scale_matrix( - dmnsn_new_vector(fabs(x2.x - x1.x)/2.0, - fabs(x2.y - x1.y)/2.0, - fabs(x2.z - x1.z)/2.0) - ); - box->trans = dmnsn_matrix_mul( - dmnsn_translation_matrix(dmnsn_new_vector((x2.x + x1.x)/2.0, - (x2.y + x1.y)/2.0, - (x2.z + x1.z)/2.0)), - box->trans - ); - - return box; -} - -static dmnsn_object * -dmnsn_realize_cone(dmnsn_astnode astnode) -{ - dmnsn_astnode pnode1, rnode1, pnode2, rnode2, open; - - if (astnode.type == DMNSN_AST_CONE) { - dmnsn_array_get(astnode.children, 0, &pnode1); - dmnsn_array_get(astnode.children, 1, &rnode1); - dmnsn_array_get(astnode.children, 2, &pnode2); - dmnsn_array_get(astnode.children, 3, &rnode2); - dmnsn_array_get(astnode.children, 4, &open); - } else if (astnode.type == DMNSN_AST_CYLINDER) { - dmnsn_array_get(astnode.children, 0, &pnode1); - dmnsn_array_get(astnode.children, 1, &pnode2); - dmnsn_array_get(astnode.children, 2, &rnode1); - dmnsn_array_get(astnode.children, 2, &rnode2); - dmnsn_array_get(astnode.children, 3, &open); - } else { - dmnsn_assert(false, "Expected a cone or cylinder."); - } - - dmnsn_vector p1 = dmnsn_realize_vector(pnode1); - dmnsn_vector p2 = dmnsn_realize_vector(pnode2); - double r1 = dmnsn_realize_float(rnode1); - double r2 = dmnsn_realize_float(rnode2); - - dmnsn_vector dir = dmnsn_vector_sub(p2, p1); - double l = dmnsn_vector_norm(dir); - - double theta1 = dmnsn_vector_axis_angle(dmnsn_y, dir, dmnsn_x); - double theta2 = dmnsn_vector_axis_angle(dmnsn_y, dir, dmnsn_z); - - dmnsn_object *cone = dmnsn_new_cone(r1, r2, dmnsn_realize_integer(open)); - /* Transformations: lift the cone to start at the origin, scale, rotate, - and translate properly */ - cone->trans = dmnsn_translation_matrix(dmnsn_new_vector(0.0, 1.0, 0.0)); - cone->trans = dmnsn_matrix_mul( - dmnsn_scale_matrix(dmnsn_new_vector(1.0, l/2.0, 1.0)), - cone->trans - ); - cone->trans = dmnsn_matrix_mul( - dmnsn_rotation_matrix(dmnsn_new_vector(theta1, 0.0, 0.0)), - cone->trans - ); - cone->trans = dmnsn_matrix_mul( - dmnsn_rotation_matrix(dmnsn_new_vector(0.0, 0.0, theta2)), - cone->trans - ); - cone->trans = dmnsn_matrix_mul( - dmnsn_translation_matrix(p1), - cone->trans - ); - return cone; -} - -static dmnsn_object * -dmnsn_realize_sphere(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_SPHERE, "Expected a sphere."); - - dmnsn_astnode center, radius; - dmnsn_array_get(astnode.children, 0, ¢er); - dmnsn_array_get(astnode.children, 1, &radius); - - dmnsn_vector x0 = dmnsn_realize_vector(center); - double r = dmnsn_realize_float(radius); - - dmnsn_object *sphere = dmnsn_new_sphere(); - sphere->trans = dmnsn_scale_matrix(dmnsn_new_vector(r, r, r)); - sphere->trans = dmnsn_matrix_mul(dmnsn_translation_matrix(x0), sphere->trans); - return sphere; -} - -static dmnsn_object * -dmnsn_realize_torus(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_TORUS, "Expected a torus."); - - dmnsn_astnode major, minor; - dmnsn_array_get(astnode.children, 0, &major); - dmnsn_array_get(astnode.children, 1, &minor); - - double R = dmnsn_realize_float(major); - double r = dmnsn_realize_float(minor); - - dmnsn_object *torus = dmnsn_new_torus(R, r); - return torus; -} - -static dmnsn_object * -dmnsn_realize_plane(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_PLANE, "Expected a plane."); - - dmnsn_astnode normal, distance; - dmnsn_array_get(astnode.children, 0, &normal); - dmnsn_array_get(astnode.children, 1, &distance); - - dmnsn_vector n = dmnsn_vector_normalize(dmnsn_realize_vector(normal)); - double d = dmnsn_realize_float(distance); - - dmnsn_object *plane = dmnsn_new_plane(n); - plane->trans = dmnsn_translation_matrix(dmnsn_vector_mul(d, n)); - return plane; -} - -/* Bulk-load a union */ -static dmnsn_object * -dmnsn_realize_union(dmnsn_astnode astnode, dmnsn_astnode modifiers, - dmnsn_array *lights) -{ - dmnsn_assert(astnode.type == DMNSN_AST_UNION, "Expected a union."); - - dmnsn_array *children = dmnsn_new_array(sizeof(dmnsn_object *)); - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, onode, astnode.children) { - if (onode->type == DMNSN_AST_LIGHT_SOURCE) { - dmnsn_light *light = dmnsn_realize_light_source(*onode); - dmnsn_realize_light_source_modifiers(modifiers, light); - dmnsn_array_push(lights, &light); - } else { - dmnsn_object *object = dmnsn_realize_object(*onode, lights); - if (object) - dmnsn_array_push(children, &object); - } - } - - dmnsn_object *csg = NULL; - if (dmnsn_array_size(children) > 0) - csg = dmnsn_new_csg_union(children); - dmnsn_delete_array(children); - return csg; -} - -typedef dmnsn_object *dmnsn_csg_object_fn(dmnsn_object *a, dmnsn_object *b); - -/* Generalized CSG realizer */ -static dmnsn_object * -dmnsn_realize_csg(dmnsn_astnode astnode, dmnsn_astnode modifiers, - dmnsn_array *lights, dmnsn_csg_object_fn *csg_object_fn) -{ - dmnsn_object *csg = NULL; - dmnsn_astnode *onode; - for (onode = dmnsn_array_first(astnode.children); - onode <= (dmnsn_astnode *)dmnsn_array_last(astnode.children); - ++onode) - { - if (onode->type == DMNSN_AST_LIGHT_SOURCE) { - dmnsn_light *light = dmnsn_realize_light_source(*onode); - dmnsn_realize_light_source_modifiers(modifiers, light); - dmnsn_array_push(lights, &light); - } else { - csg = dmnsn_realize_object(*onode, lights); - break; - } - } - - for (++onode; - onode <= (dmnsn_astnode *)dmnsn_array_last(astnode.children); - ++onode) - { - if (onode->type == DMNSN_AST_LIGHT_SOURCE) { - dmnsn_light *light = dmnsn_realize_light_source(*onode); - dmnsn_realize_light_source_modifiers(modifiers, light); - dmnsn_array_push(lights, &light); - } else { - dmnsn_object *object = dmnsn_realize_object(*onode, lights); - csg = csg_object_fn(csg, object); - } - } - - return csg; -} - -static dmnsn_object * -dmnsn_realize_intersection(dmnsn_astnode astnode, dmnsn_astnode modifiers, - dmnsn_array *lights) -{ - dmnsn_assert(astnode.type == DMNSN_AST_INTERSECTION, - "Expected an intersection."); - return dmnsn_realize_csg(astnode, modifiers, lights, - dmnsn_new_csg_intersection); -} - -static dmnsn_object * -dmnsn_realize_difference(dmnsn_astnode astnode, dmnsn_astnode modifiers, - dmnsn_array *lights) -{ - dmnsn_assert(astnode.type == DMNSN_AST_DIFFERENCE, "Expected a difference."); - return dmnsn_realize_csg(astnode, modifiers, lights, - dmnsn_new_csg_difference); -} - -static dmnsn_object * -dmnsn_realize_merge(dmnsn_astnode astnode, dmnsn_astnode modifiers, - dmnsn_array *lights) -{ - dmnsn_assert(astnode.type == DMNSN_AST_MERGE, "Expected a merge."); - return dmnsn_realize_csg(astnode, modifiers, lights, dmnsn_new_csg_merge); -} - -/* Realize an object, or maybe a light */ -static dmnsn_object * -dmnsn_realize_object(dmnsn_astnode astnode, dmnsn_array *lights) -{ - dmnsn_assert(astnode.type == DMNSN_AST_OBJECT - || astnode.type == DMNSN_AST_LIGHT_SOURCE, - "Expected an object."); - - dmnsn_astnode onode, modifiers; - dmnsn_array_get(astnode.children, 0, &onode); - dmnsn_array_get(astnode.children, 1, &modifiers); - - dmnsn_object *object = NULL; - - switch (onode.type) { - case DMNSN_AST_BOX: - object = dmnsn_realize_box(onode); - break; - case DMNSN_AST_CONE: - case DMNSN_AST_CYLINDER: - object = dmnsn_realize_cone(onode); - break; - case DMNSN_AST_DIFFERENCE: - object = dmnsn_realize_difference(onode, modifiers, lights); - break; - case DMNSN_AST_INTERSECTION: - object = dmnsn_realize_intersection(onode, modifiers, lights); - break; - case DMNSN_AST_MERGE: - object = dmnsn_realize_merge(onode, modifiers, lights); - break; - case DMNSN_AST_PLANE: - object = dmnsn_realize_plane(onode); - break; - case DMNSN_AST_SPHERE: - object = dmnsn_realize_sphere(onode); - break; - case DMNSN_AST_TORUS: - object = dmnsn_realize_torus(onode); - break; - case DMNSN_AST_UNION: - object = dmnsn_realize_union(onode, modifiers, lights); - break; - - case DMNSN_AST_LIGHT_SOURCE: - { - dmnsn_light *light = dmnsn_realize_light_source(astnode); - dmnsn_array_push(lights, &light); - return NULL; - } - - default: - dmnsn_assert(false, "Expected an object type."); - } - - if (object) { - dmnsn_realize_object_modifiers(modifiers, object); - } - return object; -} - -static dmnsn_scene * -dmnsn_realize_astree(const dmnsn_astree *astree) -{ - dmnsn_scene *scene = dmnsn_new_scene(); - - /* Default finish */ - scene->default_texture->finish = dmnsn_new_finish_combination( - dmnsn_new_ambient_finish( - dmnsn_color_mul(0.1, dmnsn_white) - ), - dmnsn_new_diffuse_finish(0.6) - ); - - /* Background color */ - scene->background = dmnsn_black; - - /* Create the default perspective camera */ - scene->camera = dmnsn_new_perspective_camera(); - - /* - * Now parse the abstract syntax tree - */ - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, astree) { - dmnsn_astnode child; - dmnsn_light *light; - dmnsn_object *object; - - switch (astnode->type) { - case DMNSN_AST_GLOBAL_SETTINGS: - dmnsn_realize_global_settings(*astnode, scene); - break; - - case DMNSN_AST_BACKGROUND: - dmnsn_array_get(astnode->children, 0, &child); - scene->background = dmnsn_realize_color(child); - break; - case DMNSN_AST_SKY_SPHERE: - dmnsn_delete_sky_sphere(scene->sky_sphere); - scene->sky_sphere = dmnsn_realize_sky_sphere(*astnode); - break; - - case DMNSN_AST_CAMERA: - dmnsn_delete_camera(scene->camera); - scene->camera = dmnsn_realize_camera(*astnode); - break; - - case DMNSN_AST_OBJECT: - object = dmnsn_realize_object(*astnode, scene->lights); - if (object) - dmnsn_array_push(scene->objects, &object); - break; - - case DMNSN_AST_LIGHT_SOURCE: - light = dmnsn_realize_light_source(*astnode); - dmnsn_array_push(scene->lights, &light); - break; - - default: - dmnsn_assert(false, "Unrecognised syntax element."); - } - } - - return scene; -} - -dmnsn_scene * -dmnsn_realize(FILE *file, dmnsn_symbol_table *symtable) -{ - if (!symtable) { - symtable = dmnsn_new_symbol_table(); - } - - dmnsn_astree *astree = dmnsn_parse(file, symtable); - if (!astree) { - return NULL; - } - - dmnsn_scene *scene = dmnsn_realize_astree(astree); - - dmnsn_delete_astree(astree); - return scene; -} - -dmnsn_scene * -dmnsn_realize_string(const char *str, dmnsn_symbol_table *symtable) -{ - if (!symtable) { - symtable = dmnsn_new_symbol_table(); - } - - dmnsn_astree *astree = dmnsn_parse_string(str, symtable); - if (!astree) { - return NULL; - } - - dmnsn_scene *scene = dmnsn_realize_astree(astree); - - dmnsn_delete_astree(astree); - return scene; -} diff --git a/dimension/realize.h b/dimension/realize.h deleted file mode 100644 index eed80fe..0000000 --- a/dimension/realize.h +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#ifndef REALIZE_H -#define REALIZE_H - -#include "dimension.h" -#include "parse.h" - -dmnsn_scene *dmnsn_realize(FILE *file, dmnsn_symbol_table *symtable); -dmnsn_scene *dmnsn_realize_string(const char *str, - dmnsn_symbol_table *symtable); - -#endif /* REALIZE_H */ diff --git a/dimension/tests/Makefile.am b/dimension/tests/Makefile.am deleted file mode 100644 index c54bcd4..0000000 --- a/dimension/tests/Makefile.am +++ /dev/null @@ -1,55 +0,0 @@ -########################################################################### -## Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> ## -## ## -## This file is part of The Dimension Build Suite. ## -## ## -## The Dimension Build Suite is free software; you can redistribute it ## -## and/or modify it under the terms of the GNU General Public License as ## -## published by the Free Software Foundation; either version 3 of the ## -## License, or (at your option) any later version. ## -## ## -## The Dimension Build Suite is distributed in the hope that it will be ## -## useful, but WITHOUT ANY WARRANTY; without even the implied warranty ## -## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## -## General Public License for more details. ## -## ## -## You should have received a copy of the GNU General Public License ## -## along with this program. If not, see <http://www.gnu.org/licenses/>. ## -########################################################################### - -INCLUDES = -I$(top_srcdir)/libdimension - -TESTS = punctuation.sh \ - numeric.sh \ - strings.sh \ - labels.sh \ - directives.sh \ - arithexp.sh \ - transformations.sh \ - invalid-macro.sh \ - tbuffer-overlap.sh \ - integer-overflow.sh \ - csg.sh \ - demo.sh -TESTS_ENVIRONMENT = top_builddir=$(top_builddir) dimension_flags=--strict - -.sh: - cp $(srcdir)/$@ . - -EXTRA_DIST = $(TESTS) \ - punctuation.pov \ - numeric.pov \ - strings.pov \ - labels.pov \ - directives.inc \ - directives.pov \ - arithexp.pov \ - transformations.pov \ - invalid-macro.pov \ - tbuffer-overlap.pov \ - integer-overflow.pov \ - csg.pov \ - demo.pov - -clean-local: - rm -f *.png diff --git a/dimension/tests/arithexp.pov b/dimension/tests/arithexp.pov deleted file mode 100644 index d38b13a..0000000 --- a/dimension/tests/arithexp.pov +++ /dev/null @@ -1,218 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test arithmetic expression handling - -sphere { - 2*<<2.0 - 1.0, 3.0, 4.0>.x, (1.0 + 2)*2 - 5, 1.0 + 2*2 - 4> - -<0, 0, 1>, - exp(1) - (0 >= 1 ? 0 : 1*2) -} - -/* Float functions */ - -#if (abs(-1) != 1) - #error "abs" -#end - -#if (acos(0) != 1.570796326794897) - #error "acos" -#end - -#if (acosh(2) != 1.316957896924817) - #error "acosh" -#end - -#if (asc("ABC") != 65) - #error "asc" -#end - -#if (asin(1) != 1.570796326794897) - #error "asin" -#end - -#if (asinh(2) != 1.44363547517881) - #error "asinh" -#end - -#if (atan(1) != 0.7853981633974483) - #error "atan" -#end - -#if (atan2(-1, -1) != -2.35619449019234) - #error "atan2" -#end - -#if (atanh(0.5) != 0.5493061443340548) - #error "atanh" -#end - -#if (ceil(-1.5) != -1) - #error "ceil" -#end - -#if (cos(1.570796326794897) != 0) - #error "cos" -#end - -#if (cosh(1.316957896924817) != 2) - #error "cosh" -#end - -#if (degrees(1.570796326794897) != 90) - #error "degrees" -#end - -#if (div(3,2) != 1) - #error "div" -#end - -#if (exp(1) != 2.718281828459045) - #error "exp" -#end - -#if (floor(-1.5) != -2) - #error "floor" -#end - -#if (int(-1.9) != -1) - #error "int" -#end - -#if (ln(2.718281828459045) != 1) - #error "ln" -#end - -#if (log(1000) != 3) - #error "log" -#end - -#if (max(-1.5, 0, 1) != 1) - #error "max" -#end - -#if (min(-1.5, 0, 1) != -1.5) - #error "min" -#end - -#if (mod(3.5, 2) != 1.5) - #error "mod" -#end - -#if (pow(2, 3) != 8) - #error "pow" -#end - -#if (radians(90) != 1.570796326794897) - #error "radians" -#end - -#if (sin(1.570796326794897) != 1) - #error "sin" -#end - -#if (sinh(1.44363547517881) != 2) - #error "sinh" -#end - -#if (strcmp("asdfjkl;", "jkl;asdf") >= 0) - #error "strcmp" -#end - -#if (strlen("asdfjkl;") != 8) - #error "strlen" -#end - -#if (sqrt(2) != 1.414213562373095) - #error "sqrt" -#end - -#if (tan(0.7853981633974483) != 1) - #error "tan" -#end - -#if (tanh(0.5493061443340548) != 0.5) - #error "tanh" -#end - -#if (val("123.45") != 123.45) - #error "val" -#end - -#if (vaxis_rotate(<1, 0, 0>, <1, 0, 1>, 180) != <0, 0, 1>) - #error "vaxis_rotate" -#end - -#if (vaxis_rotate(1, 1, 180) != <1, 1, 1>) - #error "vaxis_rotate" -#end - -#if (vcross(<1, 2, 3>, <3, 2, 1>) != <-4, 8, -4>) - #error "vcross" -#end - -#if (vcross(1, 2) != 0) - #error "vcross" -#end - -#if (vdot(<1, 2, 3>, 2) != 12) - #error "vdot" -#end - -#if (vdot(2, 2) != 12) - #error "vdot" -#end - -#if (vlength(<1, 1, 1>) != 1.732050807568877) - #error "vlength" -#end - -#if (vlength(1) != 1.732050807568877) - #error "vlength" -#end - -#if (vnormalize(<1, 1, 1>) - != <0.5773502691896258, 0.5773502691896258, 0.5773502691896258>) - #error "vnormalize" -#end - -#if (vnormalize(1) != 0.4472135954999579) // Vector promoted comparison - #error "vnormalize" -#end - -#if (vrotate(<1, 0, 0>, <0, -90, 0>) != <0, 0, 1>) - #error "vrotate" -#end - -#if (vrotate(1, 2) != <1, 1, 1>) - #error "vrotate" -#end - -/* Float built-in IDs */ - -#if (pi != 3.141592653589793) - #error "pi" -#end - -#if (!true | !yes | !on) - #error "true" -#end - -#if (false | no | off) - #error "false" -#end diff --git a/dimension/tests/arithexp.sh b/dimension/tests/arithexp.sh deleted file mode 100755 index e46ab04..0000000 --- a/dimension/tests/arithexp.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -arithexp=$(${top_builddir}/dimension/dimension ${dimension_flags} --parse ${srcdir}/arithexp.pov) -arithexp_exp="$(echo -n \ -'((object - (sphere - (vector (float 2) (float 2) (float 3) (integer 0) (integer 0)) - (float 0.718282)) - object-modifiers))' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" - -if [ "$arithexp" != "$arithexp_exp" ]; then - echo "arithexp.pov parsed as \"$arithexp\"" >&2 - echo " -- expected \"$arithexp_exp\"" >&2 - exit 1 -fi diff --git a/dimension/tests/csg.pov b/dimension/tests/csg.pov deleted file mode 100644 index 357fd7b..0000000 --- a/dimension/tests/csg.pov +++ /dev/null @@ -1,65 +0,0 @@ -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test constructive solid geometry - -camera { - perspective - location -4*z - right x*image_width/image_height - look_at 0 -} - -background { - color rgbf <0, 0.1, 0.2, 0.1> -} - -/* One-object unions */ - -union { - sphere { - -1.5*x, 1 - pigment { color red 1 } - } -} - -union { - light_source { - 20*y, color rgb 0.5 - } -} - -/* CSG with lights */ -difference { - light_source { - -15*x, color rgb 0.5 - } - sphere { - 1.5*x - 20*y, 1 - pigment { color green 1 } - } - light_source { - 15*x, color rgb 0.5 - } - box { - <0.7, -20.8, -0.8>, <2.3, -19.2, 0.8> - pigment { color blue 1 } - } - translate 20*y -} diff --git a/dimension/tests/csg.sh b/dimension/tests/csg.sh deleted file mode 100755 index b57389d..0000000 --- a/dimension/tests/csg.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2010-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -csg=$(${top_builddir}/dimension/dimension ${dimension_flags} -w768 -h480 --parse ${srcdir}/csg.pov) -csg_exp="$(echo -n \ -'((camera - perspective - (location (vector (integer 0) (integer 0) (integer -4) - (integer 0) (integer 0))) - (right (vector (float 1.6) (integer 0) (integer 0) (integer 0) (integer 0))) - (look_at (vector (integer 0) (integer 0) (integer 0) - (integer 0) (integer 0)))) - (background - (vector (integer 0) (float 0.1) (float 0.2) (float 0.1) (integer 0))) - (object - (union - (object - (sphere - (vector (float -1.5) (float 0) (float 0) (float 0) (float 0)) - (integer 1)) - (object-modifiers - (pigment - (vector (integer 1) (integer 0) (integer 0) - (integer 0) (integer 0)) - pigment-modifiers)))) - object-modifiers) - (object - (union - (light_source - (vector (integer 0) (integer 20) (integer 0) (integer 0) (integer 0)) - (vector (float 0.5) (float 0.5) (float 0.5) (integer 0) (integer 0)) - object-modifiers)) - object-modifiers) - (object - (difference - (light_source - (vector (integer -15) (integer 0) (integer 0) (integer 0) (integer 0)) - (vector (float 0.5) (float 0.5) (float 0.5) (integer 0) (integer 0)) - object-modifiers) - (object - (sphere - (vector (float 1.5) (float -20) (float 0) (float 0) (float 0)) - (integer 1)) - (object-modifiers - (pigment - (vector (integer 0) (integer 1) (integer 0) - (integer 0) (integer 0)) - pigment-modifiers))) - (light_source - (vector (integer 15) (integer 0) (integer 0) (integer 0) (integer 0)) - (vector (float 0.5) (float 0.5) (float 0.5) (integer 0) (integer 0)) - object-modifiers) - (object - (box - (vector (float 0.7) (float -20.8) (float -0.8) - (integer 0) (integer 0)) - (vector (float 2.3) (float -19.2) (float 0.8) - (integer 0) (integer 0))) - (object-modifiers - (pigment - (vector (integer 0) (integer 0) (integer 1) - (integer 0) (integer 0)) - pigment-modifiers)))) - (object-modifiers - (transformation - (translation (vector (integer 0) (integer 20) (integer 0) - (integer 0) (integer 0)))))))' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" - -if [ "$csg" != "$csg_exp" ]; then - echo "csg.pov parsed as \"$csg\"" >&2 - echo " -- expected \"$csg_exp\"" >&2 - exit 1 -fi - -${top_builddir}/dimension/dimension ${dimension_flags} -w768 -h480 -o csg.png ${srcdir}/csg.pov diff --git a/dimension/tests/demo.pov b/dimension/tests/demo.pov deleted file mode 100644 index 91be9d2..0000000 --- a/dimension/tests/demo.pov +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Render demo scene - -global_settings { - max_trace_level 5 - adc_bailout 1/255 -} - -camera { - perspective - location <0, 0.25, -4> - right x*image_width/image_height - look_at <0, 0, 0> - - rotate 53*y -} - -background { - color transmit 1 -} - -sky_sphere { - pigment { - gradient y - color_map { - [0.0 color rgb <1, 0.5, 0>] - [0.35 color rgbf <0, 0.1, 0.2, 0.1>] - } - } -} - -light_source { - <-15, 20, 10>, color rgb <1, 1, 1> -} - -difference { - box { - <-1, -1, -1>, <1, 1, 1> - - rotate 45*x - - texture { - pigment { - color rgbft <0, 0, 1, 0.25, 0.5> - } - finish { - reflection { 0.5 } - } - } - - interior { - ior 1.1 - } - } - - sphere { - <0, 0, 0>, 1.25 - - texture { - pigment { - color rgb <0, 1, 0> - } - finish { - phong 0.2 - phong_size 40.0 - } - } - } -} - -union { - cylinder { - -1.25*y, 1.25*y, 0.1 - } - cone { - 1.25*y, 0.1, 1.5*y, 0 - open - } - - pigment { - gradient y - color_map { - [0 color rgb <1, 0, 0>] - [1/6 color rgb <1, 0.5, 0>] - [2/6 color rgb <1, 1, 0>] - [3/6 color rgb <0, 1, 0>] - [4/6 color rgb <0, 0, 1>] - [5/6 color rgb <1, 0, 1>] - [1 color rgb <1, 0, 0>] - } - scale <1, 2.75, 1> - translate -1.25*y - } - rotate -45*x -} - -union { - torus { - 0.15, 0.05 - translate -y - } - torus { - 0.15, 0.05 - } - torus { - 0.15, 0.05 - translate y - } - - pigment { - color rgb <0, 0, 1> - } - finish { - ambient 1 - } - rotate -45*x -} - -plane { - y, -2 - pigment { - checker - pigment { - color rgb 1 - } - pigment { - checker color rgb 0, color rgb 1 - scale 1/3 - } - quick_color rgb <1, 0.5, 0.75> - } -} diff --git a/dimension/tests/demo.sh b/dimension/tests/demo.sh deleted file mode 100755 index 233b880..0000000 --- a/dimension/tests/demo.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -demo=$(${top_builddir}/dimension/dimension ${dimension_flags} -w768 -h480 --parse ${srcdir}/demo.pov) -demo_exp=$(echo -n \ -'((global_settings - (max_trace_level (integer 5)) - (adc_bailout (float 0.00392157))) - (camera - perspective - (location (vector (integer 0) (float 0.25) (integer -4) - (integer 0) (integer 0))) - (right (vector (float 1.6) (integer 0) (integer 0) (integer 0) (integer 0))) - (look_at (vector (integer 0) (integer 0) (integer 0) - (integer 0) (integer 0))) - (transformation - (rotation (vector (integer 0) (integer 53) (integer 0) - (integer 0) (integer 0))))) - (background - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 1))) - (sky_sphere - (pigment - (pattern - (gradient (vector (integer 0) (integer 1) - (integer 0) (integer 0) (integer 0)))) - (pigment-modifiers - (color_map - (color_map-entry - (float 0) - (vector (integer 1) (float 0.5) (integer 0) - (integer 0) (integer 0))) - (color_map-entry - (float 0.35) - (vector (integer 0) (float 0.1) (float 0.2) - (float 0.1) (integer 0))))))) - (light_source - (vector (integer -15) (integer 20) (integer 10) (integer 0) (integer 0)) - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) - object-modifiers) - (object - (difference - (object - (box - (vector (integer -1) (integer -1) (integer -1) - (integer 0) (integer 0)) - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))) - (object-modifiers - (transformation - (rotation (vector (integer 45) (integer 0) (integer 0) - (integer 0) (integer 0)))) - (texture - (pigment - (vector (integer 0) (integer 0) (integer 1) - (float 0.25) (float 0.5)) - pigment-modifiers) - (finish - (reflection - (vector (float 0.5) (float 0.5) (float 0.5) - (float 0.5) (float 0.5)) - (vector (float 0.5) (float 0.5) (float 0.5) - (float 0.5) (float 0.5)) - reflection-items))) - (interior - (ior (float 1.1))))) - (object - (sphere - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) - (float 1.25)) - (object-modifiers - (texture - (pigment - (vector (integer 0) (integer 1) (integer 0) - (integer 0) (integer 0)) - pigment-modifiers) - (finish - (phong (float 0.2)) - (phong_size (float 40))))))) - object-modifiers) - (object - (union - (object - (cylinder - (vector (float 0) (float -1.25) (float 0) (float 0) (float 0)) - (vector (float 0) (float 1.25) (float 0) (float 0) (float 0)) - (float 0.1) - (integer 0)) - object-modifiers) - (object - (cone - (vector (float 0) (float 1.25) (float 0) (float 0) (float 0)) - (float 0.1) - (vector (float 0) (float 1.5) (float 0) (float 0) (float 0)) - (integer 0) - (integer 1)) - object-modifiers)) - (object-modifiers - (pigment - (pattern (gradient (vector (integer 0) (integer 1) (integer 0) - (integer 0) (integer 0)))) - (pigment-modifiers - (color_map - (color_map-entry - (integer 0) - (vector (integer 1) (integer 0) (integer 0) - (integer 0) (integer 0))) - (color_map-entry - (float 0.166667) - (vector (integer 1) (float 0.5) (integer 0) - (integer 0) (integer 0))) - (color_map-entry - (float 0.333333) - (vector (integer 1) (integer 1) (integer 0) - (integer 0) (integer 0))) - (color_map-entry - (float 0.5) - (vector (integer 0) (integer 1) (integer 0) - (integer 0) (integer 0))) - (color_map-entry - (float 0.666667) - (vector (integer 0) (integer 0) (integer 1) - (integer 0) (integer 0))) - (color_map-entry - (float 0.833333) - (vector (integer 1) (integer 0) (integer 1) - (integer 0) (integer 0))) - (color_map-entry - (integer 1) - (vector (integer 1) (integer 0) (integer 0) - (integer 0) (integer 0)))) - (transformation - (scale (vector (integer 1) (float 2.75) (integer 1) - (integer 0) (integer 0)))) - (transformation - (translation (vector (float 0) (float -1.25) (float 0) - (float 0) (float 0)))))) - (transformation - (rotation (vector (integer -45) (integer 0) (integer 0) - (integer 0) (integer 0)))))) - (object - (union - (object - (torus (float 0.15) (float 0.05)) - (object-modifiers - (transformation - (translation (vector (integer 0) (integer -1) (integer 0) - (integer 0) (integer 0)))))) - (object - (torus (float 0.15) (float 0.05)) - object-modifiers) - (object - (torus (float 0.15) (float 0.05)) - (object-modifiers - (transformation - (translation (vector (integer 0) (integer 1) (integer 0) - (integer 0) (integer 0))))))) - (object-modifiers - (pigment - (vector (integer 0) (integer 0) (integer 1) (integer 0) (integer 0)) - pigment-modifiers) - (finish - (ambient - (vector (integer 1) (integer 1) (integer 1) (integer 1) (integer 1)))) - (transformation - (rotation (vector (integer -45) (integer 0) (integer 0) - (integer 0) (integer 0)))))) - (object - (plane - (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)) - (integer -2)) - (object-modifiers - (pigment - (pattern checker) - (pigment-modifiers - (quick_color - (vector (integer 1) (float 0.5) (float 0.75) - (integer 0) (integer 0))) - (pigment-list - (pigment - (vector (integer 1) (integer 1) (integer 1) - (integer 0) (integer 0)) - pigment-modifiers) - (pigment - (pattern checker) - (pigment-modifiers - (transformation - (scale (vector (float 0.333333) (float 0.333333) - (float 0.333333) (float 0.333333) - (float 0.333333)))) - (color-list - (vector (integer 0) (integer 0) (integer 0) - (integer 0) (integer 0)) - (vector (integer 1) (integer 1) (integer 1) - (integer 0) (integer 0)))))))))))' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g') - -if [ "$demo" != "$demo_exp" ]; then - echo "demo.pov parsed as \"$demo\"" >&2 - echo " -- expected \"$demo_exp\"" >&2 - exit 1 -fi - -${top_builddir}/dimension/dimension ${dimension_flags} -w768 -h480 -o demo.png ${srcdir}/demo.pov diff --git a/dimension/tests/directives.inc b/dimension/tests/directives.inc deleted file mode 100644 index a3dadb3..0000000 --- a/dimension/tests/directives.inc +++ /dev/null @@ -1,21 +0,0 @@ -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#declare Center = 0; -#local Local = -1; diff --git a/dimension/tests/directives.pov b/dimension/tests/directives.pov deleted file mode 100644 index 5c3cfa3..0000000 --- a/dimension/tests/directives.pov +++ /dev/null @@ -1,92 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test the language directives - -#version 3.6; - -#debug "debug" -#warning "warning" - -#include "directives.inc" - -#declare R = 1; -#local Color = rgb <1, 0, 1>; - -#declare Unused = -1; -#undef Unused - -#ifdef (Local) - #error "Local escaped from include file" -#end - -#ifdef (Unused) - #error "#undef failed" -#end - -#macro Make_Sphere(n) - sphere { - Center + <0, n, 0>, R - pigment { - color Color green 1 - } - } -#end - -#macro Inc(n) - #declare n = n + 1; -#end - -#declare Counter = 0; -#while (Counter < 2) - #if (#if (1 = 1) 0 #end = 0 & !1) - #error "Nested #if parsing failed" - #else - Make_Sphere(Counter) - #end - - Inc(Counter) -#end - -// Test macro parameters with the same name as existing variables -#declare Test1 = 0; -#declare Test2 = 1; -#declare Test3 = 2; -#macro ScopeTest(Test1, Test2, Test3) - #declare Test1 = Test2 - Test3; -#end -ScopeTest(Test1, Test3, Test2) -sphere { - 0, Test1 -} - -#declare Box = - box { - <-1, -1, -1>, <1, 1, 1> - pigment { - color rgb <1, 1, 1> - } - } - -object { - Box - finish { - phong 0.2 - } -} diff --git a/dimension/tests/directives.sh b/dimension/tests/directives.sh deleted file mode 100755 index 9e3974a..0000000 --- a/dimension/tests/directives.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -directives=$(${top_builddir}/dimension/dimension ${dimension_flags} --tokenize --parse ${srcdir}/directives.pov) -directives_exp="$(echo -n \ -'(#version (float "3.6") ; - #debug (string "debug") - #warning (string "warning") - #include (string "directives.inc") - #declare (identifier "R") = (integer "1") ; - #local (identifier "Color") = rgb < (integer "1") , (integer "0") , (integer "1") > ; - #declare (identifier "Unused") = - (integer "1") ; - #undef (identifier "Unused") - #ifdef \( (identifier "Local") \) - #error (string "Local escaped from include file") - #end - #ifdef \( (identifier "Unused") \) - #error (string "#undef failed") - #end - #macro (identifier "Make_Sphere") \( (identifier "n") \) - sphere { - (identifier "Center") + < (integer "0") , (identifier "n") , (integer "0") > , (identifier "R") - pigment { - color (identifier "Color") green (integer "1") - } - } - #end - #macro (identifier "Inc") \( (identifier "n") \) - #declare (identifier "n") = (identifier "n") + (integer "1") ; - #end - #declare (identifier "Counter") = (integer "0") ; - #while \( (identifier "Counter") < (integer "2") \) - #if \( #if \( (integer "1") = (integer "1") \) (integer "0") #end = (integer "0") & ! (integer "1") \) - #error (string "Nested #if parsing failed") - #else - (identifier "Make_Sphere") \( (identifier "Counter") \) - #end - (identifier "Inc") \( (identifier "Counter") \) - #end - - #declare (identifier "Test1") = (integer "0") ; - #declare (identifier "Test2") = (integer "1") ; - #declare (identifier "Test3") = (integer "2") ; - #macro (identifier "ScopeTest") \( (identifier "Test1") , (identifier "Test2") , (identifier "Test3") \) - #declare (identifier "Test1") = (identifier "Test2") - (identifier "Test3") ; - #end - (identifier "ScopeTest") \( (identifier "Test1") , (identifier "Test3") , (identifier "Test2") \) - sphere { - (integer "0") , (identifier "Test1") - } - - #declare (identifier "Box") = - box { - < - (integer "1") , - (integer "1") , - (integer "1") > , - < (integer "1") , (integer "1") , (integer "1") > - pigment { - color rgb < (integer "1") , (integer "1") , (integer "1") > - } - } - - object { - (identifier "Box") - finish { - phong (float "0.2") - } - })' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g') -$(echo -n \ -'((object - (sphere - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) - (integer 1)) - (object-modifiers - (pigment - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) - pigment-modifiers))) - (object - (sphere - (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)) - (integer 1)) - (object-modifiers - (pigment - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) - pigment-modifiers))) - (object - (sphere - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) - (integer 1)) - object-modifiers) - (object - (box - (vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0)) - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))) - (object-modifiers - (pigment - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) - pigment-modifiers) - (finish - (phong (float 0.2))))))' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" - -if [ "$directives" != "$directives_exp" ]; then - echo "directives.pov parsed as \"$directives\"" >&2 - echo " -- expected \"$directives_exp\"" >&2 - exit 1 -fi diff --git a/dimension/tests/integer-overflow.pov b/dimension/tests/integer-overflow.pov deleted file mode 100644 index a063fab..0000000 --- a/dimension/tests/integer-overflow.pov +++ /dev/null @@ -1,25 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test integer overflow handling -- overflows should convert to floats - -torus { - 10000000000000000000, - abs(-2147483647 - 1)*abs(-9223372036854775807 - 1)*((-2147483647 - 2)*(2147483647 + 1))*((-9223372036854775807.0 - 2)*(9223372036854775807.0 + 1))*(65536*65536)*(4294967296*4294967296.0) -} diff --git a/dimension/tests/integer-overflow.sh b/dimension/tests/integer-overflow.sh deleted file mode 100755 index 0e1f03e..0000000 --- a/dimension/tests/integer-overflow.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -integer_overflow=$(${top_builddir}/dimension/dimension ${dimension_flags} --parse ${srcdir}/integer-overflow.pov) -integer_overflow_exp="$(echo -n \ -'((object - (torus - (float 1e+19) - (float 6.15656e+113)) - object-modifiers))' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" - -if [ "$integer_overflow" != "$integer_overflow_exp" ]; then - echo "integer-overflow.pov parsed as \"$integer_overflow\"" >&2 - echo " -- expected \"$integer_overflow_exp\"" >&2 - exit 1 -fi diff --git a/dimension/tests/invalid-macro.pov b/dimension/tests/invalid-macro.pov deleted file mode 100644 index 9906da4..0000000 --- a/dimension/tests/invalid-macro.pov +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Regression test for commit 11d364ec365c46c21271012b566966d342a90a8b - -#macro Macro() - { } -#end - -Macro() diff --git a/dimension/tests/invalid-macro.sh b/dimension/tests/invalid-macro.sh deleted file mode 100755 index cf6f353..0000000 --- a/dimension/tests/invalid-macro.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -${top_builddir}/dimension/dimension ${dimension_flags} --parse ${srcdir}/invalid-macro.pov -[ $? -lt 128 -a $? -gt 0 ] diff --git a/dimension/tests/labels.pov b/dimension/tests/labels.pov deleted file mode 100644 index 369e1fd..0000000 --- a/dimension/tests/labels.pov +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test that we correctly tokenize identifiers and keywords - -camera { -} - -sphere { - color new_identifier -} - -box { - colour new_identifier -} diff --git a/dimension/tests/labels.sh b/dimension/tests/labels.sh deleted file mode 100755 index 47365bd..0000000 --- a/dimension/tests/labels.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -labels=$(${top_builddir}/dimension/dimension ${dimension_flags} --tokenize ${srcdir}/labels.pov) -labels_exp='(camera { } sphere { color (identifier "new_identifier") } box { color (identifier "new_identifier") })'; - -if [ "$labels" != "$labels_exp" ]; then - echo "labels.pov tokenized as \"$labels\"" >&2 - echo " -- expected \"$labels_exp\"" >&2 - exit 1 -fi diff --git a/dimension/tests/numeric.pov b/dimension/tests/numeric.pov deleted file mode 100644 index dbf3c19..0000000 --- a/dimension/tests/numeric.pov +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test that we correctly tokenize numeric values. Note that the `-' in `-1', -// for example, is a separate token and not part of the number. - -// Integers: -1 123456789 01234567 0x123456789 -0x01 - -// Floats: -.1 0.1 1.0 0.123456789 -0.123456789 - -// A vector: -<1, 2.2, -3.03> diff --git a/dimension/tests/numeric.sh b/dimension/tests/numeric.sh deleted file mode 100755 index c5e7c93..0000000 --- a/dimension/tests/numeric.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -numeric=$(${top_builddir}/dimension/dimension ${dimension_flags} --tokenize ${srcdir}/numeric.pov) -numeric_exp=$(echo -n \ -'((integer "1") - (integer "123456789") - (integer "01234567") - (integer "0x123456789") - - (integer "0x01") - - (float ".1") - (float "0.1") - (float "1.0") - (float "0.123456789") - - (float "0.123456789") - - < (integer "1") , (float "2.2") , - (float "3.03") >)' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g') - -if [ "$numeric" != "$numeric_exp" ]; then - echo "numeric.pov tokenized as \"$numeric\"" >&2 - echo " -- expected \"$numeric_exp\"" >&2 - exit 1 -fi diff --git a/dimension/tests/punctuation.pov b/dimension/tests/punctuation.pov deleted file mode 100644 index d61db25..0000000 --- a/dimension/tests/punctuation.pov +++ /dev/null @@ -1,24 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -/* Test that we correctly tokenize all simple punctuation marks - * // Also make sure we handle nested /* comments */ properly - */ - -{}()[]+-*/,;?:&.|=<>!<= >= != diff --git a/dimension/tests/punctuation.sh b/dimension/tests/punctuation.sh deleted file mode 100755 index 6990657..0000000 --- a/dimension/tests/punctuation.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -punctuation=$(${top_builddir}/dimension/dimension ${dimension_flags} --tokenize ${srcdir}/punctuation.pov) -punctuation_exp='({ } \( \) [ ] + - * / , ; ? : & . | = < > ! <= >= !=)' - -if [ "$punctuation" != "$punctuation_exp" ]; then - echo "punctuation.pov tokenized as \"$punctuation\"" >&2 - echo " -- expected \"$punctuation_exp\"" >&2 - exit 1 -fi diff --git a/dimension/tests/strings.pov b/dimension/tests/strings.pov deleted file mode 100644 index eafe1ba..0000000 --- a/dimension/tests/strings.pov +++ /dev/null @@ -1,21 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test string handling, including escape sequences -"This is a string with escape sequences: \a\b\f\n\r\t\u2123\v\\\'\"" diff --git a/dimension/tests/strings.sh b/dimension/tests/strings.sh deleted file mode 100755 index 1f5f4f9..0000000 --- a/dimension/tests/strings.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -strings=$(${top_builddir}/dimension/dimension ${dimension_flags} --tokenize ${srcdir}/strings.pov) -strings_exp=$(/bin/echo -e "((string \"This is a string with escape sequences: \a\b\f\n\r\t!#\v\\\'\"\"))") - -if [ "$strings" != "$strings_exp" ]; then - echo "strings.pov tokenized as \"$strings\"" >&2 - echo " -- expected \"$strings_exp\"" >&2 - exit 1 -fi diff --git a/dimension/tests/tbuffer-overlap.pov b/dimension/tests/tbuffer-overlap.pov deleted file mode 100644 index 872b124..0000000 --- a/dimension/tests/tbuffer-overlap.pov +++ /dev/null @@ -1,22 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Regression test for commit 72be096ff528306b1af6b41d5cacd1157b096d72 - -#if (1=1) #declare foo = #end; diff --git a/dimension/tests/tbuffer-overlap.sh b/dimension/tests/tbuffer-overlap.sh deleted file mode 100755 index bc3126d..0000000 --- a/dimension/tests/tbuffer-overlap.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -${top_builddir}/dimension/dimension ${dimension_flags} --parse ${srcdir}/tbuffer-overlap.pov -[ $? -lt 128 -a $? -gt 0 ] diff --git a/dimension/tests/transformations.pov b/dimension/tests/transformations.pov deleted file mode 100644 index 312445d..0000000 --- a/dimension/tests/transformations.pov +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of The Dimension Test Suite. * - * * - * The Dimension Test Suite is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Test Suite is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -// Test transformations - -#declare Trans = transform { translate 1*z } - -sphere { - 0, 1 - translate -1*x - rotate 90*y - scale 2 - transform Trans - matrix <1, 1, 0, - 0, 1, 0, - 0, 0, 1, - 0, 0, 0> - transform { - Trans - rotate 45*z - inverse - } -} diff --git a/dimension/tests/transformations.sh b/dimension/tests/transformations.sh deleted file mode 100755 index 727bf3b..0000000 --- a/dimension/tests/transformations.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/sh - -######################################################################### -# Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> # -# # -# This file is part of The Dimension Test Suite. # -# # -# The Dimension Test Suite is free software; you can redistribute it # -# and/or modify it under the terms of the GNU General Public License as # -# published by the Free Software Foundation; either version 3 of the # -# License, or (at your option) any later version. # -# # -# The Dimension Test Suite is distributed in the hope that it will be # -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <http://www.gnu.org/licenses/>. # -######################################################################### - -transformations=$(${top_builddir}/dimension/dimension ${dimension_flags} --parse ${srcdir}/transformations.pov) -transformations_exp="$(echo -n \ -'((object - (sphere - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) - (integer 1)) - (object-modifiers - (transformation - (translation - (vector (integer -1) (integer 0) (integer 0) - (integer 0) (integer 0)))) - (transformation - (rotation - (vector (integer 0) (integer 90) (integer 0) - (integer 0) (integer 0)))) - (transformation - (scale - (vector (integer 2) (integer 2) (integer 2) (integer 2) (integer 2)))) - (transformation - (translation - (vector (integer 0) (integer 0) (integer 1) (integer 0) (integer 0)))) - (transformation - (matrix - (integer 1) (integer 1) (integer 0) - (integer 0) (integer 1) (integer 0) - (integer 0) (integer 0) (integer 1) - (integer 0) (integer 0) (integer 0))) - (transformation - (translation - (vector (integer 0) (integer 0) (integer 1) (integer 0) (integer 0))) - (rotation - (vector (integer 0) (integer 0) (integer 45) - (integer 0) (integer 0))) - inverse))))' \ -| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" - -if [ "$transformations" != "$transformations_exp" ]; then - echo "transformations.pov parsed as \"$transformations\"" >&2 - echo " -- expected \"$transformations_exp\"" >&2 - exit 1 -fi - -${top_builddir}/dimension/dimension ${dimension_flags} -w1 -h1 -o /dev/null ${srcdir}/transformations.pov diff --git a/dimension/tokenize.c b/dimension/tokenize.c deleted file mode 100644 index ced6fe5..0000000 --- a/dimension/tokenize.c +++ /dev/null @@ -1,1098 +0,0 @@ -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "tokenize.h" -#include "directives.h" -#include "utility.h" -#include <libgen.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> - -typedef struct dmnsn_buffered_token { - dmnsn_token_type type; - dmnsn_parse_item lval; - dmnsn_parse_location lloc; -} dmnsn_buffered_token; - -typedef struct dmnsn_token_buffer { - dmnsn_token_type type; - /* To indicate that the first token should be returned as-is */ - #define DMNSN_T_LEX_VERBATIM DMNSN_T_EOF - - /* Whether to automatically delete this buffer if we reach its end */ - bool auto_delete; - - dmnsn_parse_location lloc; - dmnsn_array *buffered; - size_t i; - - struct dmnsn_token_buffer *prev; - - const char *filename; - void *ptr; -} dmnsn_token_buffer; - -static dmnsn_token_buffer * -dmnsn_new_token_buffer(dmnsn_parse_location lloc, dmnsn_token_type type, - dmnsn_token_buffer *prev, const char *filename) -{ - dmnsn_token_buffer *tbuffer = dmnsn_malloc(sizeof(dmnsn_token_buffer)); - tbuffer->type = type; - tbuffer->auto_delete = true; - tbuffer->lloc = lloc; - tbuffer->buffered = dmnsn_new_array(sizeof(dmnsn_buffered_token)); - tbuffer->i = 0; - tbuffer->prev = prev; - tbuffer->filename = filename; - tbuffer->ptr = NULL; - return tbuffer; -} - -static void -dmnsn_delete_token_buffer(void *ptr) -{ - dmnsn_token_buffer *tbuffer = ptr; - if (tbuffer) { - DMNSN_ARRAY_FOREACH (dmnsn_buffered_token *, buffered, tbuffer->buffered) { - dmnsn_free(buffered->lval.value); - } - - dmnsn_delete_array(tbuffer->buffered); - dmnsn_free(tbuffer); - } -} - -static int -dmnsn_yylex_wrapper(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner); -int dmnsn_ld_yyparse(const char *filename, void *yyscanner, - dmnsn_symbol_table *symtable); - -static int -dmnsn_buffer_balanced(dmnsn_token_buffer *tbuffer, bool recursive, - dmnsn_token_type left, dmnsn_token_type right, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_buffered_token buffered; - - if (tbuffer->prev) - tbuffer->prev->auto_delete = false; - - int nesting = -1; - while (1) { - if (recursive) { - buffered.type = dmnsn_yylex(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - } else { - buffered.type = dmnsn_yylex_wrapper(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - } - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - return 1; - } else if (buffered.type == DMNSN_T_LEX_ERROR) { - return 1; - } - - dmnsn_array_push(tbuffer->buffered, &buffered); - - if (buffered.type == left) { - if (nesting < 0) - nesting = 1; - else - ++nesting; - } else if (buffered.type == right) { - --nesting; - if (nesting == 0) { - break; - } - } - } - - if (tbuffer->prev) - tbuffer->prev->auto_delete = true; - - return 0; -} - -static int -dmnsn_buffer_strexp(dmnsn_token_buffer *tbuffer, bool recursive, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_buffered_token buffered; - - if (tbuffer->prev) - tbuffer->prev->auto_delete = false; - - if (recursive) { - buffered.type = dmnsn_yylex(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - } else { - buffered.type = dmnsn_yylex_wrapper(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - } - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - return 1; - } else if (buffered.type == DMNSN_T_LEX_ERROR) { - return 1; - } - /* Buffer the first token */ - dmnsn_array_push(tbuffer->buffered, &buffered); - - bool is_strexp = buffered.type != DMNSN_T_STRING; - if (buffered.type == DMNSN_T_IDENTIFIER) { - /* Check if it's a string identifier or a macro */ - dmnsn_astnode *inode = dmnsn_find_symbol(symtable, buffered.lval.value); - if (!inode || inode->type == DMNSN_AST_STRING) { - is_strexp = false; - } - } - - if (is_strexp) { - /* Grab all the tokens belonging to the string expression */ - return dmnsn_buffer_balanced(tbuffer, recursive, - DMNSN_T_LPAREN, DMNSN_T_RPAREN, - filename, symtable, yyscanner); - } - - if (tbuffer->prev) - tbuffer->prev->auto_delete = true; - - return 0; -} - -static dmnsn_token_buffer * -dmnsn_include_buffer(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *include_buffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(include_buffer->buffered, &buffered); - - /* Buffer the following string expression */ - if (dmnsn_buffer_strexp(include_buffer, true, filename, symtable, yyscanner) - != 0) - { - dmnsn_delete_token_buffer(include_buffer); - return NULL; - } - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(include_buffer->buffered, &buffered); - - dmnsn_yyset_extra(include_buffer, yyscanner); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(include_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(include_buffer); - return NULL; - } - - dmnsn_yyset_extra(include_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(include_buffer); - - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, token, prev, filename); - - dmnsn_astnode *inode = dmnsn_find_symbol(symtable, "$include"); - dmnsn_assert(inode, "$include unset."); - dmnsn_assert(inode->type == DMNSN_AST_STRING, "$include has wrong type."); - - const char *include = inode->ptr; - char *filename_copy = dmnsn_strdup(filename); - char *localdir = dirname(filename_copy); - char *local_include = dmnsn_malloc(strlen(localdir) + strlen(include) + 2); - strcpy(local_include, localdir); - strcat(local_include, "/"); - strcat(local_include, include); - dmnsn_free(filename_copy); - - FILE *file = fopen(local_include, "r"); - if (!file) { - dmnsn_diagnostic(*llocp, "Couldn't open include file '%s'", include); - dmnsn_undef_symbol(symtable, "$include"); - dmnsn_free(local_include); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - tbuffer->ptr = file; - - void *buffer = dmnsn_yy_make_buffer(file, yyscanner); - if (!buffer) { - dmnsn_diagnostic(*llocp, "Couldn't allocate buffer for include file '%s'", - include); - dmnsn_undef_symbol(symtable, "$include"); - fclose(file); - dmnsn_free(local_include); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - dmnsn_yy_push_buffer(buffer, yyscanner); - - /* Stuff the filename in the symbol table to persist it */ - dmnsn_astnode *includes = dmnsn_find_symbol(symtable, "$includes"); - if (!includes) { - dmnsn_declare_symbol(symtable, "$includes", dmnsn_new_ast_array()); - includes = dmnsn_find_symbol(symtable, "$includes"); - } - dmnsn_assert(includes, "$includes unset."); - dmnsn_assert(includes->type == DMNSN_AST_ARRAY, - "$includes has wrong type."); - - dmnsn_astnode fnode = dmnsn_new_ast_string(local_include); - dmnsn_free(local_include); - tbuffer->filename = fnode.ptr; - dmnsn_array_push(includes->children, &fnode); - - dmnsn_push_scope(symtable); - - dmnsn_undef_symbol(symtable, "$include"); - return tbuffer; -} - -static dmnsn_token_buffer * -dmnsn_declaration_buffer(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(tbuffer->buffered, &buffered); - - if (prev) - prev->auto_delete = false; - - /* Grab all the tokens belonging to the #declare/#local, i.e. until the braces - balance or we hit a semicolon */ - int bracelevel = -1; - while (1) { - /* Recursive call -- permit other directives inside the declaration */ - buffered.type = dmnsn_yylex(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } else if (buffered.type == DMNSN_T_LEX_ERROR) { - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - - dmnsn_array_push(tbuffer->buffered, &buffered); - - if (buffered.type == DMNSN_T_LBRACE) { - if (bracelevel < 0) - bracelevel = 1; - else - ++bracelevel; - } else if (buffered.type == DMNSN_T_RBRACE) { - --bracelevel; - if (bracelevel == 0) { - break; - } - } else if (buffered.type == DMNSN_T_SEMICOLON) { - break; - } - } - - if (prev) - prev->auto_delete = true; - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(tbuffer->buffered, &buffered); - - return tbuffer; -} - -static dmnsn_token_buffer * -dmnsn_undef_buffer(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(tbuffer->buffered, &buffered); - - if (prev) - prev->auto_delete = false; - /* Recursive call */ - buffered.type = dmnsn_yylex(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - if (prev) - prev->auto_delete = true; - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } else if (buffered.type == DMNSN_T_LEX_ERROR) { - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - /* Buffer the next token */ - dmnsn_array_push(tbuffer->buffered, &buffered); - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(tbuffer->buffered, &buffered); - - return tbuffer; -} - -static dmnsn_token_buffer * -dmnsn_if_buffer(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *cond_buffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(cond_buffer->buffered, &buffered); - - /* Grab all the tokens belonging to the #if (...) */ - if (dmnsn_buffer_balanced(cond_buffer, true, DMNSN_T_LPAREN, DMNSN_T_RPAREN, - filename, symtable, yyscanner) - != 0) - { - dmnsn_delete_token_buffer(cond_buffer); - return NULL; - } - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(cond_buffer->buffered, &buffered); - - dmnsn_yyset_extra(cond_buffer, yyscanner); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(cond_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(cond_buffer); - return NULL; - } - - dmnsn_yyset_extra(cond_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(cond_buffer); - - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, token, prev, filename); - - dmnsn_astnode *cnode = dmnsn_find_symbol(symtable, "$cond"); - dmnsn_assert(cnode, "$cond unset."); - - bool cond = false; - if (cnode->type == DMNSN_AST_INTEGER) { - cond = (*(long *)cnode->ptr) ? true : false; - } else if (cnode->type == DMNSN_AST_FLOAT) { - cond = (*(double *)cnode->ptr) ? true : false; - } else { - dmnsn_assert(false, "$cond has wrong type."); - } - - dmnsn_undef_symbol(symtable, "$cond"); - - if (prev) - prev->auto_delete = false; - - int nesting = 1, else_seen = 0; - while (1) { - /* Non-recursive call */ - buffered.type = dmnsn_yylex_wrapper(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - - switch (buffered.type) { - case DMNSN_T_IF: - case DMNSN_T_IFDEF: - case DMNSN_T_IFNDEF: - case DMNSN_T_MACRO: - case DMNSN_T_SWITCH: - case DMNSN_T_WHILE: - ++nesting; - break; - - case DMNSN_T_END: - --nesting; - break; - - default: - break; - } - - if (nesting == 0) { - break; - } else if (nesting == 1 && buffered.type == DMNSN_T_ELSE) { - if (else_seen - || (tbuffer->prev && tbuffer->prev->type == DMNSN_T_WHILE)) - { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected #else"); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } else { - cond = !cond; - else_seen = 1; - continue; - } - } - - if (cond) { - dmnsn_array_push(tbuffer->buffered, &buffered); - } else { - dmnsn_free(buffered.lval.value); - } - } - - if (prev) - prev->auto_delete = true; - - return tbuffer; -} - -static dmnsn_token_buffer * -dmnsn_while_buffer(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, token, prev, filename); - - /* Pretend to be an if */ - dmnsn_buffered_token buffered = { - .type = DMNSN_T_IF, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(tbuffer->buffered, &buffered); - - if (prev) - prev->auto_delete = false; - - /* Grab all the tokens belonging to the #while ... #end */ - int nesting = 1; - while (1) { - /* Non-recursive call */ - buffered.type = dmnsn_yylex_wrapper(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - - dmnsn_array_push(tbuffer->buffered, &buffered); - - switch (buffered.type) { - case DMNSN_T_IF: - case DMNSN_T_IFDEF: - case DMNSN_T_IFNDEF: - case DMNSN_T_MACRO: - case DMNSN_T_SWITCH: - case DMNSN_T_WHILE: - ++nesting; - break; - - case DMNSN_T_END: - --nesting; - break; - - default: - break; - } - - if (nesting == 0) { - break; - } - } - - if (prev) - prev->auto_delete = true; - - return tbuffer; -} - -static dmnsn_token_buffer * -dmnsn_version_buffer(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(tbuffer->buffered, &buffered); - - if (prev) - prev->auto_delete = false; - - while (buffered.type != DMNSN_T_SEMICOLON) { - /* Recursive call */ - buffered.type = dmnsn_yylex(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } else if (buffered.type == DMNSN_T_LEX_ERROR) { - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - - dmnsn_array_push(tbuffer->buffered, &buffered); - } - - if (prev) - prev->auto_delete = true; - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(tbuffer->buffered, &buffered); - - return tbuffer; -} - -static dmnsn_token_buffer * -dmnsn_stream_buffer(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(tbuffer->buffered, &buffered); - - /* Buffer the following string expression */ - if (dmnsn_buffer_strexp(tbuffer, true, filename, symtable, yyscanner) - != 0) - { - dmnsn_delete_token_buffer(tbuffer); - return NULL; - } - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(tbuffer->buffered, &buffered); - - return tbuffer; -} - -static bool -dmnsn_declare_macro(int token, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *decl_buffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(decl_buffer->buffered, &buffered); - - /* Grab all the tokens belonging to the #macro ID (...) */ - if (dmnsn_buffer_balanced(decl_buffer, true, DMNSN_T_LPAREN, DMNSN_T_RPAREN, - filename, symtable, yyscanner) - != 0) - { - dmnsn_delete_token_buffer(decl_buffer); - return false; - } - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(decl_buffer->buffered, &buffered); - - dmnsn_yyset_extra(decl_buffer, yyscanner); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(decl_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(decl_buffer); - return false; - } - - dmnsn_yyset_extra(decl_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(decl_buffer); - - dmnsn_token_buffer *tbuffer - = dmnsn_new_token_buffer(*llocp, token, NULL, filename); - - dmnsn_astnode *mname = dmnsn_find_symbol(symtable, "$macro"); - dmnsn_assert(mname, "$macro unset."); - dmnsn_assert(mname->type == DMNSN_AST_STRING, "$macro has wrong type."); - dmnsn_astnode *mnode = dmnsn_find_symbol(symtable, mname->ptr); - dmnsn_assert(mnode, "#macro unset."); - dmnsn_assert(mnode->type == DMNSN_AST_MACRO, "#macro has wrong type."); - dmnsn_undef_symbol(symtable, "$macro"); - - if (prev) - prev->auto_delete = false; - - int nesting = 1; - while (1) { - /* Non-recursive call */ - buffered.type = dmnsn_yylex_wrapper(&buffered.lval, &buffered.lloc, - filename, symtable, yyscanner); - - if (buffered.type == DMNSN_T_EOF) { - dmnsn_diagnostic(buffered.lloc, "syntax error, unexpected end-of-file"); - dmnsn_delete_token_buffer(tbuffer); - return false; - } - - switch (buffered.type) { - case DMNSN_T_IF: - case DMNSN_T_IFDEF: - case DMNSN_T_IFNDEF: - case DMNSN_T_MACRO: - case DMNSN_T_SWITCH: - case DMNSN_T_WHILE: - ++nesting; - break; - - case DMNSN_T_END: - --nesting; - break; - - default: - break; - } - - if (nesting == 0) - break; - - dmnsn_array_push(tbuffer->buffered, &buffered); - } - - if (prev) - prev->auto_delete = true; - - mnode->ptr = tbuffer; - mnode->free_fn = dmnsn_delete_token_buffer; - return true; -} - -static dmnsn_token_buffer * -dmnsn_macro_buffer(int token, dmnsn_astnode *mnode, dmnsn_token_buffer *prev, - dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *invoke_buffer - = dmnsn_new_token_buffer(*llocp, DMNSN_T_LEX_VERBATIM, prev, filename); - - /* Buffer the current token */ - dmnsn_buffered_token buffered = { - .type = token, - .lval = *lvalp, - .lloc = *llocp - }; - dmnsn_array_push(invoke_buffer->buffered, &buffered); - - /* Grab all the tokens belonging to the #macro ID (...) */ - if (dmnsn_buffer_balanced(invoke_buffer, true, DMNSN_T_LPAREN, DMNSN_T_RPAREN, - filename, symtable, yyscanner) - != 0) - { - dmnsn_delete_token_buffer(invoke_buffer); - return NULL; - } - - /* Fake EOF */ - buffered.type = DMNSN_T_EOF; - buffered.lval.value = NULL; - dmnsn_array_push(invoke_buffer->buffered, &buffered); - - dmnsn_yyset_extra(invoke_buffer, yyscanner); - dmnsn_push_scope(symtable); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(invoke_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(invoke_buffer); - return NULL; - } - - dmnsn_yyset_extra(invoke_buffer->prev, yyscanner); - dmnsn_delete_token_buffer(invoke_buffer); - - dmnsn_token_buffer *tbuffer = mnode->ptr; - tbuffer->lloc = *llocp; - tbuffer->i = 0; - tbuffer->prev = prev; - return tbuffer; -} - -int dmnsn_yylex_impl(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, void *yyscanner); - -static int -dmnsn_yylex_wrapper(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner) -{ - dmnsn_token_buffer *tbuffer = dmnsn_yyget_extra(yyscanner); - - while (tbuffer && tbuffer->type != DMNSN_T_INCLUDE - && tbuffer->i >= dmnsn_array_size(tbuffer->buffered)) - { - if (tbuffer->type == DMNSN_T_WHILE) { - tbuffer->i = 0; - } else { - if (!tbuffer->auto_delete) { - return DMNSN_T_EOF; - } - - if (dmnsn_array_size(tbuffer->buffered) == 0 - && tbuffer->prev && tbuffer->prev->type == DMNSN_T_WHILE) - { - dmnsn_yyset_extra(tbuffer->prev, yyscanner); - dmnsn_delete_token_buffer(tbuffer); - tbuffer = dmnsn_yyget_extra(yyscanner); - } - - dmnsn_yyset_extra(tbuffer->prev, yyscanner); - if (tbuffer->type == DMNSN_T_MACRO) { - dmnsn_pop_scope(symtable); - } else { - dmnsn_delete_token_buffer(tbuffer); - } - tbuffer = dmnsn_yyget_extra(yyscanner); - } - } - - int token; - - if (tbuffer && tbuffer->type != DMNSN_T_INCLUDE) { - /* Return buffered tokens */ - dmnsn_buffered_token buffered; - - dmnsn_array_get(tbuffer->buffered, tbuffer->i, &buffered); - token = buffered.type; - - if (buffered.lval.value) { - lvalp->value = dmnsn_strdup(buffered.lval.value); - } else { - lvalp->value = NULL; - } - - *llocp = buffered.lloc; - if (tbuffer->type == DMNSN_T_MACRO) - llocp->parent = &tbuffer->lloc; - ++tbuffer->i; - } else { - const char *real_filename = tbuffer ? tbuffer->filename : filename; - token = dmnsn_yylex_impl(lvalp, llocp, real_filename, yyscanner); - - if (tbuffer && tbuffer->type == DMNSN_T_INCLUDE) { - if (token == DMNSN_T_EOF) { - dmnsn_yy_pop_buffer(yyscanner); - fclose(tbuffer->ptr); - dmnsn_pop_scope(symtable); - dmnsn_yyset_extra(tbuffer->prev, yyscanner); - dmnsn_delete_token_buffer(tbuffer); - return dmnsn_yylex_wrapper(lvalp, llocp, filename, symtable, - yyscanner); - } else { - llocp->parent = &tbuffer->lloc; - } - } - } - - return token; -} - -int -dmnsn_yylex(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, void *yyscanner) -{ - /* - * So... this is kind of ugly. POV-Ray's language directives are not parsable - * by any reasonable bison grammar, since some require skipping arbitrary - * amounts of tokens, or repeatedly parsing tokens. Instead, they are - * implemented transparently by the lexer. The lexing function calls a - * separate parser to handle language directives as they arrise, and returns - * only non-directive tokens. - * - * Ideally we'd use a push parser for the language directives, but bison - * doesn't support GLR push parsers. Instead, we buffer all the appropriate - * tokens and call a pull parser, then discard the buffer and continue. - */ - - while (1) { - int token = dmnsn_yylex_wrapper( - lvalp, llocp, filename, symtable, yyscanner - ); - dmnsn_token_buffer *tbuffer = dmnsn_yyget_extra(yyscanner); - - if (tbuffer && tbuffer->type == DMNSN_T_LEX_VERBATIM && tbuffer->i == 1) { - return token; - } - - switch (token) { - case DMNSN_T_INCLUDE: - { - dmnsn_token_buffer *tb = dmnsn_include_buffer( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - break; - } - - case DMNSN_T_DECLARE: - case DMNSN_T_LOCAL: - { - dmnsn_token_buffer *tb = dmnsn_declaration_buffer( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - return DMNSN_T_LEX_ERROR; - } - - /* Restore the previous extra pointer */ - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - break; - } - - case DMNSN_T_UNDEF: - { - dmnsn_token_buffer *tb = dmnsn_undef_buffer( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - return DMNSN_T_LEX_ERROR; - } - - /* Restore the previous extra pointer */ - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - break; - } - - case DMNSN_T_IF: - case DMNSN_T_IFDEF: - case DMNSN_T_IFNDEF: - { - dmnsn_token_buffer *tb = dmnsn_if_buffer( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - break; - } - - case DMNSN_T_WHILE: - { - dmnsn_token_buffer *tb = dmnsn_while_buffer( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - break; - } - - case DMNSN_T_VERSION: - { - dmnsn_token_buffer *tb = dmnsn_version_buffer( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - return DMNSN_T_LEX_ERROR; - } - - /* Restore the previous extra pointer */ - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - break; - } - - case DMNSN_T_DEBUG: - case DMNSN_T_ERROR: - case DMNSN_T_WARNING: - { - dmnsn_token_buffer *tb = dmnsn_stream_buffer( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - if (dmnsn_ld_yyparse(filename, yyscanner, symtable) != 0) { - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - return DMNSN_T_LEX_ERROR; - } - - /* Restore the previous extra pointer */ - dmnsn_yyset_extra(tb->prev, yyscanner); - dmnsn_delete_token_buffer(tb); - break; - } - - case DMNSN_T_MACRO: - { - bool status = dmnsn_declare_macro( - token, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!status) { - return DMNSN_T_LEX_ERROR; - } - break; - } - - case DMNSN_T_IDENTIFIER: - { - dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, lvalp->value); - if (symbol && symbol->type == DMNSN_AST_MACRO) { - dmnsn_token_buffer *tb = dmnsn_macro_buffer( - token, symbol, tbuffer, lvalp, llocp, filename, symtable, yyscanner - ); - if (!tb) { - return DMNSN_T_LEX_ERROR; - } - - dmnsn_yyset_extra(tb, yyscanner); - break; - } else { - return token; - } - } - - default: - return token; - } - } -} - -void -dmnsn_yylex_cleanup(void *yyscanner) -{ - dmnsn_token_buffer *tbuffer = dmnsn_yyget_extra(yyscanner); - while (tbuffer) { - if (tbuffer->type == DMNSN_T_INCLUDE) { - dmnsn_yy_pop_buffer(yyscanner); - fclose(tbuffer->ptr); - } - - dmnsn_token_buffer *prev = tbuffer->prev; - if (tbuffer->type != DMNSN_T_MACRO) - dmnsn_delete_token_buffer(tbuffer); - tbuffer = prev; - } - dmnsn_yyset_extra(NULL, yyscanner); -} diff --git a/dimension/tokenize.h b/dimension/tokenize.h deleted file mode 100644 index ca1b3e3..0000000 --- a/dimension/tokenize.h +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#ifndef TOKENIZE_H -#define TOKENIZE_H - -#include "dimension.h" -#include "parse.h" - -#define yytokentype dmnsn_yytokentype -#define YYSTYPE -#define YYLTYPE - -#include "grammar.h" - -#undef YYLTYPE -#undef YYSTYPE -#undef yytokentype - -typedef enum dmnsn_yytokentype dmnsn_token_type; - -typedef struct dmnsn_token dmnsn_token; - -struct dmnsn_token { - dmnsn_token_type type; - char *value; - - /* File name, and line and column numbers from source code */ - const char *filename; - int line, col; -}; - -/* Scanner manipulation */ - -int dmnsn_yylex_init(void **scannerp); -void dmnsn_yyset_in(FILE *file, void *scanner); -int dmnsn_yylex_destroy(void *scanner); -void *dmnsn_yyget_extra(void *scanner); -void dmnsn_yyset_extra(void *arbitrary_data, void *scanner); - -void *dmnsn_yy_make_buffer(FILE *file, void *scanner); -void *dmnsn_yy_make_string_buffer(const char *str, void *scanner); -void dmnsn_yy_push_buffer(void *buffer, void *scanner); -void dmnsn_yy_pop_buffer(void *scanner); - -/* Actual lexer */ -int dmnsn_yylex(dmnsn_parse_item *lvalp, dmnsn_parse_location *llocp, - const char *filename, dmnsn_symbol_table *symtable, - void *yyscanner); -void dmnsn_yylex_cleanup(void *yyscanner); - -/* For debugging - returns an array of raw tokens */ -dmnsn_array *dmnsn_tokenize(FILE *file, const char *filename); - -/* Token destruction */ -void dmnsn_delete_tokens(dmnsn_array *tokens); - -/* Print an S-expression of a list of tokens to `file' */ -void dmnsn_print_token_sexpr(FILE *file, const dmnsn_array *tokens); - -/* Returns a readable name for a token type (ex. DMNSN_T_FLOAT -> float) */ -const char *dmnsn_token_string(dmnsn_token_type token_type); - -#endif /* TOKENIZE_H */ diff --git a/dimension/utility.c b/dimension/utility.c deleted file mode 100644 index 88d7f79..0000000 --- a/dimension/utility.c +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "utility.h" -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <stdarg.h> -#include <stdio.h> - -bool -dmnsn_strtoi(int *n, const char *nptr, int base) -{ - long ln; - bool ret = dmnsn_strtol(&ln, nptr, base); - *n = ln; - return ret && ln <= INT_MAX && ln >= INT_MIN; -} - -bool -dmnsn_strtol(long *n, const char *nptr, int base) -{ - char *endptr; - errno = 0; - *n = strtol(nptr, &endptr, base); - return *endptr == '\0' && endptr != nptr && errno == 0; -} - -bool -dmnsn_strtoui(unsigned int *n, const char *nptr, int base) -{ - /* Skip leading whitespace to detect a leading minus sign */ - while (isspace(*nptr)) { - ++nptr; - } - bool neg = false; - if (nptr[0] == '-') { - ++nptr; - if (nptr[0] == '-' || nptr[0] == '+') { - return false; - } - neg = true; - } - - unsigned long ln; - bool ret = dmnsn_strtoul(&ln, nptr, base); - if (neg) { - *n = -ln; - } else { - *n = ln; - } - return ret && (ln <= UINT_MAX || nptr[0] == '-'); -} - -bool -dmnsn_strtoul(unsigned long *n, const char *nptr, int base) -{ - char *endptr; - errno = 0; - *n = strtoul(nptr, &endptr, base); - return *endptr == '\0' && endptr != nptr && errno == 0; -} - -bool -dmnsn_strtod(double *n, const char *nptr) -{ - char *endptr; - errno = 0; - *n = strtod(nptr, &endptr); - return *endptr == '\0' && endptr != nptr - && (errno == 0 || (errno == ERANGE && *n == 0.0)); -} - -void -dmnsn_diagnostic(dmnsn_parse_location location, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - - if (location.first_line >= 0 && location.first_column >= 0) { - if (location.first_line != location.last_line) { - fprintf(stderr, "%s:%d-%d: ", location.first_filename, - location.first_line, location.last_line); - } else if (location.first_column != location.last_column - 1) { - fprintf(stderr, "%s:%d:%d-%d: ", location.first_filename, - location.first_line, location.first_column, location.last_column); - } else { - fprintf(stderr, "%s:%d:%d: ", location.first_filename, - location.first_line, location.first_column); - } - } else { - fprintf(stderr, "%s: ", location.first_filename); - } - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - - va_end(ap); - - if (location.parent) { - dmnsn_diagnostic(*location.parent, "-- from here"); - } -} diff --git a/dimension/utility.h b/dimension/utility.h deleted file mode 100644 index 13cfdf5..0000000 --- a/dimension/utility.h +++ /dev/null @@ -1,43 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#ifndef UTILITY_H -#define UTILITY_H - -#include "parse.h" /* For dmnsn_parse_location */ -#include <stdbool.h> - -/* Wrappers for strtol and strtoul, and some added ones */ -bool dmnsn_strtoi(int *n, const char *nptr, int base); -bool dmnsn_strtol(long *n, const char *nptr, int base); -bool dmnsn_strtoui(unsigned int *n, const char *nptr, int base); -bool dmnsn_strtoul(unsigned long *n, const char *nptr, int base); -bool dmnsn_strtod(double *n, const char *nptr); - -#if defined(__GNUC__) || defined(__attribute__) - #define DMNSN_PRINTF_WARN(f, a) __attribute__((format (printf, f, a))) -#else - #define DMNSN_PRINTF_WARN(f, a) -#endif - -/* Print a parsing diagnostic to stderr */ -void dmnsn_diagnostic(dmnsn_parse_location location, const char *format, ...) - DMNSN_PRINTF_WARN(2, 3); - -#endif /* UTILITY_H */ diff --git a/dimension/y.tab.h b/dimension/y.tab.h deleted file mode 100644 index 940e3e2..0000000 --- a/dimension/y.tab.h +++ /dev/null @@ -1,21 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -/* Hack around automake sucking */ -#include "grammar.h" |