summaryrefslogtreecommitdiffstats
path: root/dimension
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2011-05-15 16:10:51 -0600
committerTavian Barnes <tavianator@gmail.com>2011-05-15 16:10:51 -0600
commite5e88afdbf158e6df8f8c3328f308512819d9cf3 (patch)
tree2a011762c07c0087defcdc1f1022ffe32d532f49 /dimension
parenta5a6b94c038e01ebf1e2de0a0774a69b02fb8e1e (diff)
downloaddimension-e5e88afdbf158e6df8f8c3328f308512819d9cf3.tar.xz
Rip out old client.
Diffstat (limited to 'dimension')
-rw-r--r--dimension/Makefile.am88
-rw-r--r--dimension/bench/Makefile.am35
-rw-r--r--dimension/bench/bench.pov118
-rwxr-xr-xdimension/bench/parse.sh59
-rwxr-xr-xdimension/bench/render.sh25
-rwxr-xr-xdimension/bench/tokenize.sh24
-rw-r--r--dimension/common.declarations33
-rw-r--r--dimension/common.nonterminals117
-rw-r--r--dimension/common.prologue154
-rw-r--r--dimension/common.rules1177
-rw-r--r--dimension/common.terminals526
-rw-r--r--dimension/directives.declarations29
-rw-r--r--dimension/directives.nonterminals27
-rw-r--r--dimension/directives.prologue35
-rw-r--r--dimension/directives.rules180
-rw-r--r--dimension/grammar.declarations31
-rw-r--r--dimension/grammar.epilogue284
-rw-r--r--dimension/grammar.nonterminals35
-rw-r--r--dimension/grammar.prologue27
-rw-r--r--dimension/grammar.rules127
-rw-r--r--dimension/lexer.l494
-rw-r--r--dimension/main.c376
-rw-r--r--dimension/parse.c1679
-rw-r--r--dimension/parse.h284
-rw-r--r--dimension/platform.c41
-rw-r--r--dimension/platform.h31
-rw-r--r--dimension/progressbar.c51
-rw-r--r--dimension/progressbar.h31
-rw-r--r--dimension/realize.c1450
-rw-r--r--dimension/realize.h30
-rw-r--r--dimension/tests/Makefile.am55
-rw-r--r--dimension/tests/arithexp.pov218
-rwxr-xr-xdimension/tests/arithexp.sh35
-rw-r--r--dimension/tests/csg.pov65
-rwxr-xr-xdimension/tests/csg.sh94
-rw-r--r--dimension/tests/demo.pov150
-rwxr-xr-xdimension/tests/demo.sh220
-rw-r--r--dimension/tests/directives.inc21
-rw-r--r--dimension/tests/directives.pov92
-rwxr-xr-xdimension/tests/directives.sh124
-rw-r--r--dimension/tests/integer-overflow.pov25
-rwxr-xr-xdimension/tests/integer-overflow.sh35
-rw-r--r--dimension/tests/invalid-macro.pov26
-rwxr-xr-xdimension/tests/invalid-macro.sh23
-rw-r--r--dimension/tests/labels.pov31
-rwxr-xr-xdimension/tests/labels.sh29
-rw-r--r--dimension/tests/numeric.pov30
-rwxr-xr-xdimension/tests/numeric.sh43
-rw-r--r--dimension/tests/punctuation.pov24
-rwxr-xr-xdimension/tests/punctuation.sh29
-rw-r--r--dimension/tests/strings.pov21
-rwxr-xr-xdimension/tests/strings.sh29
-rw-r--r--dimension/tests/tbuffer-overlap.pov22
-rwxr-xr-xdimension/tests/tbuffer-overlap.sh23
-rw-r--r--dimension/tests/transformations.pov39
-rwxr-xr-xdimension/tests/transformations.sh64
-rw-r--r--dimension/tokenize.c1098
-rw-r--r--dimension/tokenize.h80
-rw-r--r--dimension/utility.c118
-rw-r--r--dimension/utility.h43
-rw-r--r--dimension/y.tab.h21
61 files changed, 0 insertions, 10525 deletions
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, &param);
- 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, &center);
- 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"