diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | dimension/Makefile.am | 16 | ||||
-rw-r--r-- | dimension/grammar.declarations | 38 | ||||
-rw-r--r-- | dimension/grammar.epilogue | 148 | ||||
-rw-r--r-- | dimension/grammar.nonterminals | 83 | ||||
-rw-r--r-- | dimension/grammar.prologue | 153 | ||||
-rw-r--r-- | dimension/grammar.rules | 562 | ||||
-rw-r--r-- | dimension/grammar.terminals | 519 | ||||
-rw-r--r-- | dimension/grammar.y | 1419 |
9 files changed, 1520 insertions, 1419 deletions
@@ -42,6 +42,7 @@ Makefile.in /dimension/dimension /dimension/grammar.c /dimension/grammar.h +/dimension/grammar.y /dimension/lexer.c # Files created by `make check' diff --git a/dimension/Makefile.am b/dimension/Makefile.am index 1d18374..1ee125c 100644 --- a/dimension/Makefile.am +++ b/dimension/Makefile.am @@ -23,6 +23,22 @@ bin_PROGRAMS = dimension AM_YFLAGS = -d BUILT_SOURCES = grammar.h +EXTRA_DIST = grammar.prologue \ + grammar.declarations \ + grammar.terminals \ + grammar.nonterminals \ + grammar.rules \ + grammar.epilogue + +grammar.y: grammar.prologue grammar.declarations grammar.terminals grammar.nonterminals grammar.rules grammar.epilogue + echo "%{" >$@ + cat grammar.prologue >>$@ + echo "%}" >>$@ + cat grammar.{declarations,terminals,nonterminals} >>$@ + echo "%%" >>$@ + cat grammar.rules >>$@ + echo "%%" >>$@ + cat grammar.epilogue >>$@ dimension_SOURCES = grammar.y \ lexer.l \ diff --git a/dimension/grammar.declarations b/dimension/grammar.declarations new file mode 100644 index 0000000..c951758 --- /dev/null +++ b/dimension/grammar.declarations @@ -0,0 +1,38 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.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 +%token-table + +%name-prefix "dmnsn_yy" + +%expect 10 +%glr-parser + +%parse-param {const char *filename} +%parse-param {void *yyscanner} +%parse-param {dmnsn_astree *astree} +%parse-param {dmnsn_symbol_table *symtable} +%lex-param {const char *filename} +%lex-param {void *yyscanner} + +%destructor { free($$); } <value> +%destructor { dmnsn_delete_astnode($$); } <astnode> diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue new file mode 100644 index 0000000..345fa0f --- /dev/null +++ b/dimension/grammar.epilogue @@ -0,0 +1,148 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.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); + + if (yyparse(filename, scanner, astree, symtable) != 0) { + dmnsn_delete_astree(astree); + astree = NULL; + } + + 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_ROTATION, "rotate"); + dmnsn_astnode_map(DMNSN_AST_SCALE, "scale"); + dmnsn_astnode_map(DMNSN_AST_TRANSLATION, "translate"); + + 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_BACKGROUND, "background"); + + dmnsn_astnode_map(DMNSN_AST_BOX, "box"); + dmnsn_astnode_map(DMNSN_AST_SPHERE, "sphere"); + dmnsn_astnode_map(DMNSN_AST_LIGHT_SOURCE, "light_source"); + + dmnsn_astnode_map(DMNSN_AST_OBJECT_MODIFIERS, "object-modifiers"); + + dmnsn_astnode_map(DMNSN_AST_TEXTURE, "texture"); + + dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment"); + + 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_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_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_COLOR, "color"); + + dmnsn_astnode_map(DMNSN_AST_IDENTIFIER, "identifier"); + + dmnsn_astnode_map(DMNSN_AST_STRING, "string"); + + 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 new file mode 100644 index 0000000..ae752c3 --- /dev/null +++ b/dimension/grammar.nonterminals @@ -0,0 +1,83 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.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 + +/* Language directives */ +%type <astnode> RVALUE +%type <astnode> IDENTIFIER + +/* Transformations */ +%type <astnode> TRANSFORMATION + +/* 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 + +/* Atmospheric effects */ +%type <astnode> ATMOSPHERIC_EFFECT +%type <astnode> BACKGROUND + +/* Objects */ +%type <astnode> OBJECT +%type <astnode> FINITE_SOLID_OBJECT +%type <astnode> BOX +%type <astnode> LIGHT_SOURCE +%type <astnode> SPHERE + +/* Object modifiers */ +%type <astnode> OBJECT_MODIFIERS +%type <astnode> OBJECT_MODIFIER + +/* Textures */ +%type <astnode> TEXTURE +%type <astnode> TEXTURE_ITEMS + +/* Pigments */ +%type <astnode> PIGMENT +%type <astnode> PIGMENT_TYPE + +/* Finishes */ +%type <astnode> FINISH +%type <astnode> FINISH_ITEMS +%type <astnode> REFLECTION +%type <astnode> REFLECTION_ITEMS + +/* Floats */ +%type <astnode> FLOAT +%type <astnode> FLOAT_LITERAL + +/* Vectors */ +%type <astnode> VECTOR +%type <astnode> VECTOR_LITERAL + +/* Generalized arithmetic expressions */ +%type <astnode> ARITH_EXPR + +/* 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/grammar.prologue b/dimension/grammar.prologue new file mode 100644 index 0000000..7b0db1f --- /dev/null +++ b/dimension/grammar.prologue @@ -0,0 +1,153 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.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 <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; \ + } else { \ + (Current).first_filename = (Current).last_filename = \ + YYRHSLOC(Rhs, 0).last_filename; \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC(Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC(Rhs, 0).last_column; \ + } \ + } while (0) + +/* Create a new astnode, populating filename, line, and col */ + +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, + .refcount = malloc(sizeof(unsigned int)), + .filename = lloc.first_filename, + .line = lloc.first_line, + .col = lloc.first_column + }; + + if (!astnode.refcount) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate reference count."); + } + *astnode.refcount = 1; + + return astnode; +} + +/* Semi-shallow copy */ +static void +dmnsn_copy_children(dmnsn_astnode dest, dmnsn_astnode src) +{ + unsigned int i; + for (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; +} + +void +yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, + dmnsn_astree *astree, dmnsn_symbol_table *symtable, const char *str) +{ + dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column, + "%s", str); +} diff --git a/dimension/grammar.rules b/dimension/grammar.rules new file mode 100644 index 0000000..2558485 --- /dev/null +++ b/dimension/grammar.rules @@ -0,0 +1,562 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.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 LANGUAGE_DIRECTIVE + | SCENE SCENE_ITEM { + dmnsn_array_push(astree, &$2); + } +; + +/* Language directives */ + +LANGUAGE_DIRECTIVE: DECLARATION +; + +DECLARATION: "#declare" "identifier" "=" RVALUE { + dmnsn_declare_symbol(symtable, $2, $4); + free($2); + dmnsn_delete_astnode($4); + } + | "#local" "identifier" "=" RVALUE { + dmnsn_local_symbol(symtable, $2, $4); + free($2); + dmnsn_delete_astnode($4); + } + | "#undef" "identifier" { + dmnsn_undef_symbol(symtable, $2); + free($2); + } +; + +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 +; + +IDENTIFIER: "identifier" { + $$ = dmnsn_new_astnode(DMNSN_AST_IDENTIFIER, @$); + $$.ptr = $1; + } +; + +/* Top-level scene item */ +SCENE_ITEM: ATMOSPHERIC_EFFECT + | CAMERA + | OBJECT +; + +/* Transformations */ + +TRANSFORMATION: "rotate" VECTOR { + $$ = dmnsn_new_astnode1(DMNSN_AST_ROTATION, @$, $2); + } + | "scale" VECTOR { + $$ = dmnsn_new_astnode1(DMNSN_AST_SCALE, @$, $2); + } + | "translate" VECTOR { + $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSLATION, @$, $2); + } +; + +/* 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_astnode(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 +; + +/* Atmospheric effects */ + +ATMOSPHERIC_EFFECT: BACKGROUND +; + +BACKGROUND: "background" "{" COLOR "}" { + $$ = dmnsn_new_astnode1(DMNSN_AST_BACKGROUND, @$, $3); + } +; + +/* Objects */ + +OBJECT: FINITE_SOLID_OBJECT + | LIGHT_SOURCE +; + +FINITE_SOLID_OBJECT: BOX + | SPHERE +; + +BOX: "box" "{" + VECTOR "," VECTOR + OBJECT_MODIFIERS + "}" + { + $$ = dmnsn_new_astnode3(DMNSN_AST_BOX, @$, $3, $5, $6); + } +; + +LIGHT_SOURCE: "light_source" "{" + VECTOR "," COLOR + "}" + { + $$ = dmnsn_new_astnode2(DMNSN_AST_LIGHT_SOURCE, @$, $3, $5); + } +; + +SPHERE: "sphere" "{" + VECTOR "," FLOAT + OBJECT_MODIFIERS + "}" + { + $$ = dmnsn_new_astnode3(DMNSN_AST_SPHERE, @$, $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 { + $$ = dmnsn_new_astnode1(DMNSN_AST_TEXTURE, @$, $1); + } +; + +/* 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); + } +; + +/* Pigments */ + +PIGMENT: "pigment" "{" + PIGMENT_TYPE + "}" + { + $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT, @$, $3); + } +; + +PIGMENT_TYPE: /* empty */ { + $$ = dmnsn_new_astnode(DMNSN_AST_NONE, @$); + } + | COLOR +; + +/* 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); + } +; + +/* Floats */ + +FLOAT: ARITH_EXPR { + $$ = dmnsn_eval_scalar($1, symtable); + dmnsn_delete_astnode($1); + + if ($$.type == DMNSN_AST_NONE) { + dmnsn_delete_astnode($$); + YYERROR; + } + } +; + +FLOAT_LITERAL: "integer" { + $$ = dmnsn_new_astnode(DMNSN_AST_INTEGER, @$); + $$.ptr = malloc(sizeof(long)); + if (!$$.ptr) + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Failed to allocate room for integer."); + + *(long *)$$.ptr = strtol($1, NULL, 0); + free($1); + } + | "float" { + $$ = dmnsn_new_astnode(DMNSN_AST_FLOAT, @$); + $$.ptr = malloc(sizeof(double)); + if (!$$.ptr) + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Failed to allocate room for float."); + + *(double *)$$.ptr = strtod($1, NULL); + free($1); + } +; + +/* 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 ")" { $$ = $2; } + | IDENTIFIER +; + +/* Colors */ + +COLOR: COLOR_BODY { + $$ = $1; + $$.type = DMNSN_AST_COLOR; + } + | "color" COLOR_BODY { + $$ = $2; + $$.type = DMNSN_AST_COLOR; + } +; + +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_astnode(DMNSN_AST_INTEGER, @$); + zero.ptr = malloc(sizeof(long)); + if (!zero.ptr) + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Failed to allocate room for integer."); + *(long *)zero.ptr = 0; + + $$ = dmnsn_eval_vector(zero, symtable); + dmnsn_delete_astnode(zero); + } +; + +COLOR_KEYWORD_ITEM: "identifier" { + dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, $1); + if (!symbol) { + dmnsn_diagnostic(@1.first_filename, @1.first_line, + @1.first_column, + "unbound identifier '%s'", $1); + free($1); + YYERROR; + } else if (symbol->type != DMNSN_AST_COLOR) { + dmnsn_astnode eval = dmnsn_eval_vector(*symbol, symtable); + if (eval.type == DMNSN_AST_NONE) { + free($1); + YYERROR; + } + + dmnsn_copy_children($<astnode>0, eval); + dmnsn_delete_astnode(eval); + } else { + dmnsn_copy_children($<astnode>0, *symbol); + } + + free($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/grammar.terminals b/dimension/grammar.terminals new file mode 100644 index 0000000..586715b --- /dev/null +++ b/dimension/grammar.terminals @@ -0,0 +1,519 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.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 END 0 "end-of-file" + +/* 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 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 +%token DMNSN_T_ABSORPTION +%token DMNSN_T_ACCURACY +%token DMNSN_T_ACOS +%token DMNSN_T_ACOSH +%token DMNSN_T_ADAPTIVE +%token DMNSN_T_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 +%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 +%token DMNSN_T_ASCII +%token DMNSN_T_ASIN +%token DMNSN_T_ASINH +%token DMNSN_T_ASSUMED_GAMMA +%token DMNSN_T_ATAN +%token DMNSN_T_ATAN2 +%token DMNSN_T_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 +%token DMNSN_T_CELLS +%token DMNSN_T_CHARSET +%token DMNSN_T_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 +%token DMNSN_T_COMPONENT +%token DMNSN_T_COMPOSITE +%token DMNSN_T_CONCAT +%token DMNSN_T_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 +%token DMNSN_T_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 +%token DMNSN_T_CYLINDRICAL +%token DMNSN_T_DEFINED +%token DMNSN_T_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 +%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 +%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 +%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 +%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 +%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 +%token DMNSN_T_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 +%token DMNSN_T_IMAGE_MAP +%token DMNSN_T_IMAGE_PATTERN +%token DMNSN_T_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 +%token DMNSN_T_INTERIOR +%token DMNSN_T_INTERIOR_TEXTURE +%token DMNSN_T_INTERNAL +%token DMNSN_T_INTERPOLATE +%token DMNSN_T_INTERSECTION +%token DMNSN_T_INTERVALS +%token DMNSN_T_INVERSE +%token DMNSN_T_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 +%token DMNSN_T_LOAD_FILE +%token DMNSN_T_LOCATION "location" +%token DMNSN_T_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 +%token DMNSN_T_MAX +%token DMNSN_T_MAX_EXTENT +%token DMNSN_T_MAX_GRADIENT +%token DMNSN_T_MAX_INTERSECTIONS +%token DMNSN_T_MAX_ITERATION +%token DMNSN_T_MAX_SAMPLE +%token DMNSN_T_MAX_TRACE +%token DMNSN_T_MAX_TRACE_LEVEL +%token DMNSN_T_MEDIA +%token DMNSN_T_MEDIA_ATTENUATION +%token DMNSN_T_MEDIA_INTERACTION +%token DMNSN_T_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 +%token DMNSN_T_MIN_EXTENT +%token DMNSN_T_MINIMUM_REUSE +%token DMNSN_T_MOD +%token DMNSN_T_MORTAR +%token DMNSN_T_NATURAL_SPLINE +%token DMNSN_T_NEAREST_COUNT +%token DMNSN_T_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 +%token DMNSN_T_OCTAVES +%token DMNSN_T_OFF +%token DMNSN_T_OFFSET +%token DMNSN_T_OMEGA +%token DMNSN_T_OMNIMAX +%token DMNSN_T_ON +%token DMNSN_T_ONCE +%token DMNSN_T_ONION +%token DMNSN_T_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 +%token DMNSN_T_PIGMENT "pigment" +%token DMNSN_T_PIGMENT_MAP +%token DMNSN_T_PIGMENT_PATTERN +%token DMNSN_T_PLANAR +%token DMNSN_T_PLANE +%token DMNSN_T_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 +%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 +%token DMNSN_T_QUILTED +%token DMNSN_T_RADIAL +%token DMNSN_T_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 +%token DMNSN_T_SINE_WAVE +%token DMNSN_T_SINH +%token DMNSN_T_SIZE +%token DMNSN_T_SKY "sky" +%token DMNSN_T_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 +%token DMNSN_T_STR +%token DMNSN_T_STRCMP +%token DMNSN_T_STRENGTH +%token DMNSN_T_STRLEN +%token DMNSN_T_STRLWR +%token DMNSN_T_STRUPR +%token DMNSN_T_STURM +%token DMNSN_T_SUBSTR +%token DMNSN_T_SUM +%token DMNSN_T_SUPERELLIPSOID +%token DMNSN_T_SYS +%token DMNSN_T_T "t" +%token DMNSN_T_TAN +%token DMNSN_T_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 +%token DMNSN_T_TRACE +%token DMNSN_T_TRANSFORM +%token DMNSN_T_TRANSLATE "translate" +%token DMNSN_T_TRANSMIT "transmit" +%token DMNSN_T_TRIANGLE +%token DMNSN_T_TRIANGLE_WAVE +%token DMNSN_T_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 +%token DMNSN_T_UP "up" +%token DMNSN_T_USE_ALPHA +%token DMNSN_T_USE_COLOR +%token DMNSN_T_USE_INDEX +%token DMNSN_T_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 +%token DMNSN_T_VARIANCE +%token DMNSN_T_VAXIS_ROTATE +%token DMNSN_T_VCROSS +%token DMNSN_T_VDOT +%token DMNSN_T_VERTEX_VECTORS +%token DMNSN_T_VLENGTH +%token DMNSN_T_VNORMALIZE +%token DMNSN_T_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 +%token DMNSN_T_Z "z" + +/* Directives (#declare etc.) */ +%token DMNSN_T_BREAK +%token DMNSN_T_CASE +%token DMNSN_T_DEBUG +%token DMNSN_T_DECLARE "#declare" +%token DMNSN_T_DEFAULT +%token DMNSN_T_ELSE +%token DMNSN_T_END +%token DMNSN_T_ERROR +%token DMNSN_T_FCLOSE +%token DMNSN_T_FOPEN +%token DMNSN_T_IF +%token DMNSN_T_IFDEF +%token DMNSN_T_IFNDEF +%token DMNSN_T_INCLUDE "#include" +%token DMNSN_T_LOCAL "#local" +%token DMNSN_T_MACRO +%token DMNSN_T_RANGE +%token DMNSN_T_READ +%token DMNSN_T_RENDER +%token DMNSN_T_STATISTICS +%token DMNSN_T_SWITCH +%token DMNSN_T_UNDEF "#undef" +%token DMNSN_T_VERSION +%token DMNSN_T_WARNING +%token DMNSN_T_WHILE +%token DMNSN_T_WRITE + +/* Identifiers */ +%token <value> DMNSN_T_IDENTIFIER "identifier" + +/* Strings */ +%token <value> DMNSN_T_STRING "string" diff --git a/dimension/grammar.y b/dimension/grammar.y deleted file mode 100644 index b41100f..0000000 --- a/dimension/grammar.y +++ /dev/null @@ -1,1419 +0,0 @@ -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.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 <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; \ - } else { \ - (Current).first_filename = (Current).last_filename = \ - YYRHSLOC(Rhs, 0).last_filename; \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC(Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC(Rhs, 0).last_column; \ - } \ - } while (0) - -/* Create a new astnode, populating filename, line, and col */ - -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, - .refcount = malloc(sizeof(unsigned int)), - .filename = lloc.first_filename, - .line = lloc.first_line, - .col = lloc.first_column - }; - - if (!astnode.refcount) { - dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate reference count."); - } - *astnode.refcount = 1; - - return astnode; -} - -/* Semi-shallow copy */ -static void -dmnsn_copy_children(dmnsn_astnode dest, dmnsn_astnode src) -{ - unsigned int i; - for (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; -} - -void -yyerror(YYLTYPE *locp, const char *filename, void *yyscanner, - dmnsn_astree *astree, dmnsn_symbol_table *symtable, const char *str) -{ - dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column, - "%s", str); -} -%} - -%define api.pure -%locations -%error-verbose -%token-table - -%name-prefix "dmnsn_yy" - -%expect 10 -%glr-parser - -%parse-param {const char *filename} -%parse-param {void *yyscanner} -%parse-param {dmnsn_astree *astree} -%parse-param {dmnsn_symbol_table *symtable} -%lex-param {const char *filename} -%lex-param {void *yyscanner} - -%token END 0 "end-of-file" - -/* 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 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 -%token DMNSN_T_ABSORPTION -%token DMNSN_T_ACCURACY -%token DMNSN_T_ACOS -%token DMNSN_T_ACOSH -%token DMNSN_T_ADAPTIVE -%token DMNSN_T_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 -%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 -%token DMNSN_T_ASCII -%token DMNSN_T_ASIN -%token DMNSN_T_ASINH -%token DMNSN_T_ASSUMED_GAMMA -%token DMNSN_T_ATAN -%token DMNSN_T_ATAN2 -%token DMNSN_T_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 -%token DMNSN_T_CELLS -%token DMNSN_T_CHARSET -%token DMNSN_T_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 -%token DMNSN_T_COMPONENT -%token DMNSN_T_COMPOSITE -%token DMNSN_T_CONCAT -%token DMNSN_T_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 -%token DMNSN_T_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 -%token DMNSN_T_CYLINDRICAL -%token DMNSN_T_DEFINED -%token DMNSN_T_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 -%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 -%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 -%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 -%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 -%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 -%token DMNSN_T_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 -%token DMNSN_T_IMAGE_MAP -%token DMNSN_T_IMAGE_PATTERN -%token DMNSN_T_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 -%token DMNSN_T_INTERIOR -%token DMNSN_T_INTERIOR_TEXTURE -%token DMNSN_T_INTERNAL -%token DMNSN_T_INTERPOLATE -%token DMNSN_T_INTERSECTION -%token DMNSN_T_INTERVALS -%token DMNSN_T_INVERSE -%token DMNSN_T_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 -%token DMNSN_T_LOAD_FILE -%token DMNSN_T_LOCATION "location" -%token DMNSN_T_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 -%token DMNSN_T_MAX -%token DMNSN_T_MAX_EXTENT -%token DMNSN_T_MAX_GRADIENT -%token DMNSN_T_MAX_INTERSECTIONS -%token DMNSN_T_MAX_ITERATION -%token DMNSN_T_MAX_SAMPLE -%token DMNSN_T_MAX_TRACE -%token DMNSN_T_MAX_TRACE_LEVEL -%token DMNSN_T_MEDIA -%token DMNSN_T_MEDIA_ATTENUATION -%token DMNSN_T_MEDIA_INTERACTION -%token DMNSN_T_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 -%token DMNSN_T_MIN_EXTENT -%token DMNSN_T_MINIMUM_REUSE -%token DMNSN_T_MOD -%token DMNSN_T_MORTAR -%token DMNSN_T_NATURAL_SPLINE -%token DMNSN_T_NEAREST_COUNT -%token DMNSN_T_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 -%token DMNSN_T_OCTAVES -%token DMNSN_T_OFF -%token DMNSN_T_OFFSET -%token DMNSN_T_OMEGA -%token DMNSN_T_OMNIMAX -%token DMNSN_T_ON -%token DMNSN_T_ONCE -%token DMNSN_T_ONION -%token DMNSN_T_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 -%token DMNSN_T_PIGMENT "pigment" -%token DMNSN_T_PIGMENT_MAP -%token DMNSN_T_PIGMENT_PATTERN -%token DMNSN_T_PLANAR -%token DMNSN_T_PLANE -%token DMNSN_T_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 -%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 -%token DMNSN_T_QUILTED -%token DMNSN_T_RADIAL -%token DMNSN_T_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 -%token DMNSN_T_SINE_WAVE -%token DMNSN_T_SINH -%token DMNSN_T_SIZE -%token DMNSN_T_SKY "sky" -%token DMNSN_T_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 -%token DMNSN_T_STR -%token DMNSN_T_STRCMP -%token DMNSN_T_STRENGTH -%token DMNSN_T_STRLEN -%token DMNSN_T_STRLWR -%token DMNSN_T_STRUPR -%token DMNSN_T_STURM -%token DMNSN_T_SUBSTR -%token DMNSN_T_SUM -%token DMNSN_T_SUPERELLIPSOID -%token DMNSN_T_SYS -%token DMNSN_T_T "t" -%token DMNSN_T_TAN -%token DMNSN_T_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 -%token DMNSN_T_TRACE -%token DMNSN_T_TRANSFORM -%token DMNSN_T_TRANSLATE "translate" -%token DMNSN_T_TRANSMIT "transmit" -%token DMNSN_T_TRIANGLE -%token DMNSN_T_TRIANGLE_WAVE -%token DMNSN_T_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 -%token DMNSN_T_UP "up" -%token DMNSN_T_USE_ALPHA -%token DMNSN_T_USE_COLOR -%token DMNSN_T_USE_INDEX -%token DMNSN_T_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 -%token DMNSN_T_VARIANCE -%token DMNSN_T_VAXIS_ROTATE -%token DMNSN_T_VCROSS -%token DMNSN_T_VDOT -%token DMNSN_T_VERTEX_VECTORS -%token DMNSN_T_VLENGTH -%token DMNSN_T_VNORMALIZE -%token DMNSN_T_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 -%token DMNSN_T_Z "z" - -/* Directives (#declare etc.) */ -%token DMNSN_T_BREAK -%token DMNSN_T_CASE -%token DMNSN_T_DEBUG -%token DMNSN_T_DECLARE "#declare" -%token DMNSN_T_DEFAULT -%token DMNSN_T_ELSE -%token DMNSN_T_END -%token DMNSN_T_ERROR -%token DMNSN_T_FCLOSE -%token DMNSN_T_FOPEN -%token DMNSN_T_IF -%token DMNSN_T_IFDEF -%token DMNSN_T_IFNDEF -%token DMNSN_T_INCLUDE "#include" -%token DMNSN_T_LOCAL "#local" -%token DMNSN_T_MACRO -%token DMNSN_T_RANGE -%token DMNSN_T_READ -%token DMNSN_T_RENDER -%token DMNSN_T_STATISTICS -%token DMNSN_T_SWITCH -%token DMNSN_T_UNDEF "#undef" -%token DMNSN_T_VERSION -%token DMNSN_T_WARNING -%token DMNSN_T_WHILE -%token DMNSN_T_WRITE - -/* Identifiers */ -%token <value> DMNSN_T_IDENTIFIER "identifier" - -/* Strings */ -%token <value> DMNSN_T_STRING "string" - -/* Top-level items */ -%type <astnode> SCENE_ITEM - -/* Language directives */ -%type <astnode> RVALUE -%type <astnode> IDENTIFIER - -/* Transformations */ -%type <astnode> TRANSFORMATION - -/* 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 - -/* Atmospheric effects */ -%type <astnode> ATMOSPHERIC_EFFECT -%type <astnode> BACKGROUND - -/* Objects */ -%type <astnode> OBJECT -%type <astnode> FINITE_SOLID_OBJECT -%type <astnode> BOX -%type <astnode> LIGHT_SOURCE -%type <astnode> SPHERE - -/* Object modifiers */ -%type <astnode> OBJECT_MODIFIERS -%type <astnode> OBJECT_MODIFIER - -/* Textures */ -%type <astnode> TEXTURE -%type <astnode> TEXTURE_ITEMS - -/* Pigments */ -%type <astnode> PIGMENT -%type <astnode> PIGMENT_TYPE - -/* Finishes */ -%type <astnode> FINISH -%type <astnode> FINISH_ITEMS -%type <astnode> REFLECTION -%type <astnode> REFLECTION_ITEMS - -/* Floats */ -%type <astnode> FLOAT -%type <astnode> FLOAT_LITERAL - -/* Vectors */ -%type <astnode> VECTOR -%type <astnode> VECTOR_LITERAL - -/* Generalized arithmetic expressions */ -%type <astnode> ARITH_EXPR - -/* Colors */ -%type <astnode> COLOR -%type <astnode> COLOR_BODY -%type <astnode> COLOR_VECTOR -%type <astnode> COLOR_KEYWORD_GROUP -%type <astnode> COLOR_KEYWORD_GROUP_INIT - -%destructor { free($$); } <value> -%destructor { dmnsn_delete_astnode($$); } <astnode> - -%% - -/* Start symbol */ - -SCENE: /* empty */ - | SCENE LANGUAGE_DIRECTIVE - | SCENE SCENE_ITEM { - dmnsn_array_push(astree, &$2); - } -; - -/* Language directives */ - -LANGUAGE_DIRECTIVE: DECLARATION -; - -DECLARATION: "#declare" "identifier" "=" RVALUE { - dmnsn_declare_symbol(symtable, $2, $4); - free($2); - dmnsn_delete_astnode($4); - } - | "#local" "identifier" "=" RVALUE { - dmnsn_local_symbol(symtable, $2, $4); - free($2); - dmnsn_delete_astnode($4); - } - | "#undef" "identifier" { - dmnsn_undef_symbol(symtable, $2); - free($2); - } -; - -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 -; - -IDENTIFIER: "identifier" { - $$ = dmnsn_new_astnode(DMNSN_AST_IDENTIFIER, @$); - $$.ptr = $1; - } -; - -/* Top-level scene item */ -SCENE_ITEM: ATMOSPHERIC_EFFECT - | CAMERA - | OBJECT -; - -/* Transformations */ - -TRANSFORMATION: "rotate" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_ROTATION, @$, $2); - } - | "scale" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_SCALE, @$, $2); - } - | "translate" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSLATION, @$, $2); - } -; - -/* 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_astnode(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 -; - -/* Atmospheric effects */ - -ATMOSPHERIC_EFFECT: BACKGROUND -; - -BACKGROUND: "background" "{" COLOR "}" { - $$ = dmnsn_new_astnode1(DMNSN_AST_BACKGROUND, @$, $3); - } -; - -/* Objects */ - -OBJECT: FINITE_SOLID_OBJECT - | LIGHT_SOURCE -; - -FINITE_SOLID_OBJECT: BOX - | SPHERE -; - -BOX: "box" "{" - VECTOR "," VECTOR - OBJECT_MODIFIERS - "}" - { - $$ = dmnsn_new_astnode3(DMNSN_AST_BOX, @$, $3, $5, $6); - } -; - -LIGHT_SOURCE: "light_source" "{" - VECTOR "," COLOR - "}" - { - $$ = dmnsn_new_astnode2(DMNSN_AST_LIGHT_SOURCE, @$, $3, $5); - } -; - -SPHERE: "sphere" "{" - VECTOR "," FLOAT - OBJECT_MODIFIERS - "}" - { - $$ = dmnsn_new_astnode3(DMNSN_AST_SPHERE, @$, $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 { - $$ = dmnsn_new_astnode1(DMNSN_AST_TEXTURE, @$, $1); - } -; - -/* 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); - } -; - -/* Pigments */ - -PIGMENT: "pigment" "{" - PIGMENT_TYPE - "}" - { - $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT, @$, $3); - } -; - -PIGMENT_TYPE: /* empty */ { - $$ = dmnsn_new_astnode(DMNSN_AST_NONE, @$); - } - | COLOR -; - -/* 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); - } -; - -/* Floats */ - -FLOAT: ARITH_EXPR { - $$ = dmnsn_eval_scalar($1, symtable); - dmnsn_delete_astnode($1); - - if ($$.type == DMNSN_AST_NONE) { - dmnsn_delete_astnode($$); - YYERROR; - } - } -; - -FLOAT_LITERAL: "integer" { - $$ = dmnsn_new_astnode(DMNSN_AST_INTEGER, @$); - $$.ptr = malloc(sizeof(long)); - if (!$$.ptr) - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Failed to allocate room for integer."); - - *(long *)$$.ptr = strtol($1, NULL, 0); - free($1); - } - | "float" { - $$ = dmnsn_new_astnode(DMNSN_AST_FLOAT, @$); - $$.ptr = malloc(sizeof(double)); - if (!$$.ptr) - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Failed to allocate room for float."); - - *(double *)$$.ptr = strtod($1, NULL); - free($1); - } -; - -/* 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 ")" { $$ = $2; } - | IDENTIFIER -; - -/* Colors */ - -COLOR: COLOR_BODY { - $$ = $1; - $$.type = DMNSN_AST_COLOR; - } - | "color" COLOR_BODY { - $$ = $2; - $$.type = DMNSN_AST_COLOR; - } -; - -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_astnode(DMNSN_AST_INTEGER, @$); - zero.ptr = malloc(sizeof(long)); - if (!zero.ptr) - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Failed to allocate room for integer."); - *(long *)zero.ptr = 0; - - $$ = dmnsn_eval_vector(zero, symtable); - dmnsn_delete_astnode(zero); - } -; - -COLOR_KEYWORD_ITEM: "identifier" { - dmnsn_astnode *symbol = dmnsn_find_symbol(symtable, $1); - if (!symbol) { - dmnsn_diagnostic(@1.first_filename, @1.first_line, - @1.first_column, - "unbound identifier '%s'", $1); - free($1); - YYERROR; - } else if (symbol->type != DMNSN_AST_COLOR) { - dmnsn_astnode eval = dmnsn_eval_vector(*symbol, symtable); - if (eval.type == DMNSN_AST_NONE) { - free($1); - YYERROR; - } - - dmnsn_copy_children($<astnode>0, eval); - dmnsn_delete_astnode(eval); - } else { - dmnsn_copy_children($<astnode>0, *symbol); - } - - free($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); - } -; - -%% - -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); - - if (yyparse(filename, scanner, astree, symtable) != 0) { - dmnsn_delete_astree(astree); - astree = NULL; - } - - 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_ROTATION, "rotate"); - dmnsn_astnode_map(DMNSN_AST_SCALE, "scale"); - dmnsn_astnode_map(DMNSN_AST_TRANSLATION, "translate"); - - 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_BACKGROUND, "background"); - - dmnsn_astnode_map(DMNSN_AST_BOX, "box"); - dmnsn_astnode_map(DMNSN_AST_SPHERE, "sphere"); - dmnsn_astnode_map(DMNSN_AST_LIGHT_SOURCE, "light_source"); - - dmnsn_astnode_map(DMNSN_AST_OBJECT_MODIFIERS, "object-modifiers"); - - dmnsn_astnode_map(DMNSN_AST_TEXTURE, "texture"); - - dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment"); - - 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_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_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_COLOR, "color"); - - dmnsn_astnode_map(DMNSN_AST_IDENTIFIER, "identifier"); - - dmnsn_astnode_map(DMNSN_AST_STRING, "string"); - - default: - fprintf(stderr, "Warning: unrecognised astnode type %d.\n", - (int)astnode_type); - return "unrecognized-astnode"; - } -} |