summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-10-31 14:05:02 -0400
committerTavian Barnes <tavianator@gmail.com>2009-10-31 14:05:02 -0400
commit92efb5d0d7ba0c2b49cf189d5055bc0d9b09994c (patch)
tree8634a495a71efac721e1fae8fd2b61461fbcdea9
parentff94c67ce80d6baf4677c4564796e163b8d6b5aa (diff)
downloaddimension-92efb5d0d7ba0c2b49cf189d5055bc0d9b09994c.tar.xz
Implement dmnsn_print_astree_sexpr().
-rw-r--r--dimension/parse.c104
-rw-r--r--dimension/parse.h5
-rw-r--r--dimension/tokenize.c18
-rw-r--r--dimension/tokenize.h2
-rwxr-xr-xtests/dimension/box.sh10
5 files changed, 114 insertions, 25 deletions
diff --git a/dimension/parse.c b/dimension/parse.c
index b8085d8..42a48bd 100644
--- a/dimension/parse.c
+++ b/dimension/parse.c
@@ -35,13 +35,13 @@ dmnsn_parse_expect(dmnsn_token_type type, const dmnsn_array *tokens,
if (token.type != type) {
dmnsn_diagnostic(token.filename, token.line, token.col,
"Expected '%s', found '%s'",
- dmnsn_token_name(type),
- dmnsn_token_name(token.type));
+ dmnsn_token_string(type),
+ dmnsn_token_string(token.type));
return 1;
}
} else {
fprintf(stderr, "Expected '%s', found end of file\n",
- dmnsn_token_name(type));
+ dmnsn_token_string(type));
return 1;
}
@@ -57,8 +57,8 @@ dmnsn_parse_float(const dmnsn_array *tokens, unsigned int *ip,
if (i >= dmnsn_array_size(tokens)) {
fprintf(stderr, "Expected '%s' or '%s', found end of file\n",
- dmnsn_token_name(DMNSN_T_INTEGER),
- dmnsn_token_name(DMNSN_T_FLOAT));
+ dmnsn_token_string(DMNSN_T_INTEGER),
+ dmnsn_token_string(DMNSN_T_FLOAT));
return 1;
}
@@ -72,8 +72,8 @@ dmnsn_parse_float(const dmnsn_array *tokens, unsigned int *ip,
++i;
if (i >= dmnsn_array_size(tokens)) {
fprintf(stderr, "Expected '%s' or '%s', found end of file\n",
- dmnsn_token_name(DMNSN_T_INTEGER),
- dmnsn_token_name(DMNSN_T_FLOAT));
+ dmnsn_token_string(DMNSN_T_INTEGER),
+ dmnsn_token_string(DMNSN_T_FLOAT));
return 1;
}
dmnsn_array_get(tokens, i, &token);
@@ -88,9 +88,9 @@ dmnsn_parse_float(const dmnsn_array *tokens, unsigned int *ip,
++i;
} else {
fprintf(stderr, "Expected '%s' or '%s', found '%s'\n",
- dmnsn_token_name(DMNSN_T_INTEGER),
- dmnsn_token_name(DMNSN_T_FLOAT),
- dmnsn_token_name(token.type));
+ dmnsn_token_string(DMNSN_T_INTEGER),
+ dmnsn_token_string(DMNSN_T_FLOAT),
+ dmnsn_token_string(token.type));
return 1;
}
@@ -214,8 +214,8 @@ dmnsn_parse(const dmnsn_array *tokens)
if (dmnsn_parse_box(tokens, &i, astree) != 0) {
dmnsn_diagnostic(token.filename, token.line, token.col,
"Invalid box",
- dmnsn_token_name(DMNSN_T_BOX),
- dmnsn_token_name(token.type));
+ dmnsn_token_string(DMNSN_T_BOX),
+ dmnsn_token_string(token.type));
goto bailout;
}
break;
@@ -223,7 +223,7 @@ dmnsn_parse(const dmnsn_array *tokens)
default:
dmnsn_diagnostic(token.filename, token.line, token.col,
"Unexpected token '%s'",
- dmnsn_token_name(token.type));
+ dmnsn_token_string(token.type));
goto bailout;
}
}
@@ -263,7 +263,83 @@ dmnsn_delete_astree(dmnsn_array *astree)
}
}
+static void
+dmnsn_print_astnode(FILE *file, dmnsn_astnode astnode)
+{
+ double dvalue;
+
+ switch (astnode.type) {
+ case DMNSN_AST_FLOAT:
+ dvalue = *(double *)astnode.ptr;
+ fprintf(file, "(%s %g)", dmnsn_astnode_string(astnode.type), dvalue);
+ break;
+
+ default:
+ fprintf(file, "%s", dmnsn_astnode_string(astnode.type));
+ }
+}
+
+static void
+dmnsn_print_astree(FILE *file, dmnsn_astnode astnode)
+{
+ unsigned int i;
+ dmnsn_astnode child;
+
+ if (astnode.children) {
+ fprintf(file, "(");
+ dmnsn_print_astnode(file, astnode);
+ for (i = 0; i < dmnsn_array_size(astnode.children); ++i) {
+ dmnsn_array_get(astnode.children, i, &child);
+ fprintf(file, " ");
+ dmnsn_print_astree(file, child);
+ }
+ fprintf(file, ")");
+ } else {
+ dmnsn_print_astnode(file, astnode);
+ }
+}
+
void
-dmnsn_print_astree_sexpr(FILE *file, const dmnsn_array *tokens)
+dmnsn_print_astree_sexpr(FILE *file, const dmnsn_array *astree)
{
+ dmnsn_astnode astnode;
+ unsigned int i;
+
+ if (dmnsn_array_size(astree) == 0) {
+ fprintf(file, "()");
+ } else {
+ fprintf(file, "(");
+ dmnsn_array_get(astree, 0, &astnode);
+ dmnsn_print_astree(file, astnode);
+
+ for (i = 1; i < dmnsn_array_size(astree); ++i) {
+ fprintf(file, " ");
+ dmnsn_array_get(astree, i, &astnode);
+ dmnsn_print_astree(file, astnode);
+ }
+
+ fprintf(file, ")");
+ }
+
+ fprintf(file, "\n");
+}
+
+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_BOX, "box");
+ dmnsn_astnode_map(DMNSN_AST_VECTOR, "vector");
+ dmnsn_astnode_map(DMNSN_AST_FLOAT, "float");
+
+ default:
+ fprintf(stderr, "Warning: unrecognised astnode type %d.\n",
+ (int)astnode_type);
+ return "unrecognized-astnode";
+ }
}
diff --git a/dimension/parse.h b/dimension/parse.h
index aa6ee58..0b818bf 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -44,4 +44,7 @@ dmnsn_array *dmnsn_parse(const dmnsn_array *tokens);
void dmnsn_delete_astree(dmnsn_array *astree);
/* Print an S-expression of the abstract syntax tree to `file' */
-void dmnsn_print_astree_sexpr(FILE *file, const dmnsn_array *tokens);
+void dmnsn_print_astree_sexpr(FILE *file, const dmnsn_array *astree);
+
+/* Returns a readable name for a token type (ex. DMNSN_T_FLOAT -> float) */
+const char *dmnsn_astnode_string(dmnsn_astnode_type astnode_type);
diff --git a/dimension/tokenize.c b/dimension/tokenize.c
index acd48f5..94543f1 100644
--- a/dimension/tokenize.c
+++ b/dimension/tokenize.c
@@ -1043,19 +1043,19 @@ dmnsn_delete_tokens(dmnsn_array *tokens)
}
static void
-dmnsn_print_token(FILE *file, const dmnsn_token *token)
+dmnsn_print_token(FILE *file, dmnsn_token token)
{
const char *tname;
- if (token->type == DMNSN_T_LPAREN) {
+ if (token.type == DMNSN_T_LPAREN) {
tname = "\\(";
- } else if (token->type == DMNSN_T_RPAREN) {
+ } else if (token.type == DMNSN_T_RPAREN) {
tname = "\\)";
} else {
- tname = dmnsn_token_name(token->type);
+ tname = dmnsn_token_string(token.type);
}
- if (token->value) {
- fprintf(file, "(%s \"%s\")", tname, token->value);
+ if (token.value) {
+ fprintf(file, "(%s \"%s\")", tname, token.value);
} else {
fprintf(file, "%s", tname);
}
@@ -1072,12 +1072,12 @@ dmnsn_print_token_sexpr(FILE *file, const dmnsn_array *tokens)
} else {
fprintf(file, "(");
dmnsn_array_get(tokens, 0, &token);
- dmnsn_print_token(file, &token);
+ dmnsn_print_token(file, token);
for (i = 1; i < dmnsn_array_size(tokens); ++i) {
fprintf(file, " ");
dmnsn_array_get(tokens, i, &token);
- dmnsn_print_token(file, &token);
+ dmnsn_print_token(file, token);
}
fprintf(file, ")");
@@ -1087,7 +1087,7 @@ dmnsn_print_token_sexpr(FILE *file, const dmnsn_array *tokens)
}
const char *
-dmnsn_token_name(dmnsn_token_type token_type)
+dmnsn_token_string(dmnsn_token_type token_type)
{
switch (token_type) {
/* Macro to shorten this huge switch */
diff --git a/dimension/tokenize.h b/dimension/tokenize.h
index 894ee13..4eb1109 100644
--- a/dimension/tokenize.h
+++ b/dimension/tokenize.h
@@ -535,4 +535,4 @@ void dmnsn_delete_tokens(dmnsn_array *tokens);
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_name(dmnsn_token_type token_type);
+const char *dmnsn_token_string(dmnsn_token_type token_type);
diff --git a/tests/dimension/box.sh b/tests/dimension/box.sh
index 244b6fa..7a9f754 100755
--- a/tests/dimension/box.sh
+++ b/tests/dimension/box.sh
@@ -19,4 +19,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
#########################################################################
+box=$(${top_builddir}/dimension/dimension --tokenize --parse ${srcdir}/box.pov)
+box_exp='(box { < - (float "0.125") , - (integer "1") , - (integer "1") > , < (float "0.125") , (integer "1") , (integer "1") > } box { < - (integer "1") , - (integer "1") , - (float "0.125") > , < (integer "1") , (integer "1") , (float "0.125") > })
+((box (vector (float -0.125) (float -1) (float -1)) (vector (float 0.125) (float 1) (float 1))) (box (vector (float -1) (float -1) (float -0.125)) (vector (float 1) (float 1) (float 0.125))))'
+
+if [ "$box" != "$box_exp" ]; then
+ echo "box.pov parsed as \"$box\"" >&2
+ echo " -- expected \"$box_exp\"" >&2
+ exit 1
+fi
+
${top_builddir}/dimension/dimension -o box.png ${srcdir}/box.pov