diff options
author | Tavian Barnes <tavianator@gmail.com> | 2009-10-31 14:05:02 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2009-10-31 14:05:02 -0400 |
commit | 92efb5d0d7ba0c2b49cf189d5055bc0d9b09994c (patch) | |
tree | 8634a495a71efac721e1fae8fd2b61461fbcdea9 /dimension | |
parent | ff94c67ce80d6baf4677c4564796e163b8d6b5aa (diff) | |
download | dimension-92efb5d0d7ba0c2b49cf189d5055bc0d9b09994c.tar.xz |
Implement dmnsn_print_astree_sexpr().
Diffstat (limited to 'dimension')
-rw-r--r-- | dimension/parse.c | 104 | ||||
-rw-r--r-- | dimension/parse.h | 5 | ||||
-rw-r--r-- | dimension/tokenize.c | 18 | ||||
-rw-r--r-- | dimension/tokenize.h | 2 |
4 files changed, 104 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); |