summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-10-14 21:24:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-10-14 21:24:31 -0700
commit8807a16fe3115e19ce4d65f1c8beb476494ccaec (patch)
treef61b0adc3c66f76415553c4d114fe784f97c5e70
parent68e4d78cf9f153871d9a3c07c8ce3e43eb517c3b (diff)
downloadtxr-8807a16fe3115e19ce4d65f1c8beb476494ccaec.tar.gz
txr-8807a16fe3115e19ce4d65f1c8beb476494ccaec.tar.bz2
txr-8807a16fe3115e19ce4d65f1c8beb476494ccaec.zip
More type safety, with help from C++ compiler.
* parser.h (scanner_t): New typedef. Cleverly, we use yyguts_t as the basis for this, which pays off in a few places, getting rid of conversions. (parser_t): scanner member redeclared to scanner_t *. (yyerror, yyerr, yyerrof, end_of_regex, end_of_char): Declarations updated. * parser.l (yyerror, yyerrorf, num_esc): scanner argument becomes scanner_t * instead of void *. (yyscanner): Occurrences replaced by yyg: why should we refer to the type-unsafe void *yyscanner, when we know that in the middle of the yylex function we have the properly typed yyguts_t *yyg. (end_of_regex, end_of_char): Argument changes to scanner_t * and name strategically changes to yyg, eliminating the local variable and cast. * parser.y (sym_helper): scanner argument becomes scanner_t * instead of void *. (%parse-param}: void *scnr becomes scanner_t *scnr. (define-transform, yybadtoken): Use scanner_t * instead of void *. (parse): Since yylex_init takes a void **, we use it to initialize a local void *, and then assign it to the structure member.
-rw-r--r--ChangeLog27
-rw-r--r--parser.h14
-rw-r--r--parser.l40
-rw-r--r--parser.y14
4 files changed, 61 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index fb23e8e8..fd8d0bfb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,32 @@
2014-10-14 Kaz Kylheku <kaz@kylheku.com>
+ More type safety, with help from C++ compiler.
+
+ * parser.h (scanner_t): New typedef. Cleverly, we use
+ yyguts_t as the basis for this, which pays off in
+ a few places, getting rid of conversions.
+ (parser_t): scanner member redeclared to scanner_t *.
+ (yyerror, yyerr, yyerrof, end_of_regex, end_of_char):
+ Declarations updated.
+
+ * parser.l (yyerror, yyerrorf, num_esc): scanner argument becomes
+ scanner_t * instead of void *.
+ (yyscanner): Occurrences replaced by yyg: why should we
+ refer to the type-unsafe void *yyscanner, when we know that
+ in the middle of the yylex function we have the properly
+ typed yyguts_t *yyg.
+ (end_of_regex, end_of_char): Argument changes to scanner_t * and name
+ strategically changes to yyg, eliminating the local variable and cast.
+
+ * parser.y (sym_helper): scanner argument becomes
+ scanner_t * instead of void *.
+ (%parse-param}: void *scnr becomes scanner_t *scnr.
+ (define-transform, yybadtoken): Use scanner_t * instead of void *.
+ (parse): Since yylex_init takes a void **, we use it to initialize
+ a local void *, and then assign it to the structure member.
+
+2014-10-14 Kaz Kylheku <kaz@kylheku.com>
+
C++ upkeep.
TXR's support for compiling as C++ pays off: C++ compiler finds
diff --git a/parser.h b/parser.h
index bb85d01c..532fbfb1 100644
--- a/parser.h
+++ b/parser.h
@@ -24,6 +24,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+typedef struct yyguts_t scanner_t;
+
typedef struct {
cnum lineno;
int errors;
@@ -31,17 +33,17 @@ typedef struct {
val name;
val prepared_msg;
val syntax_tree;
- void *scanner;
+ scanner_t *scanner;
} parser_t;
extern const wchar_t *spec_file;
extern val form_to_ln_hash;
-void yyerror(void *scanner, parser_t *, const char *s);
-void yyerr(void *scanner, const char *s);
-void yyerrorf(void *scanner, val s, ...);
+void yyerror(scanner_t *scanner, parser_t *, const char *s);
+void yyerr(scanner_t *scanner, const char *s);
+void yyerrorf(scanner_t *scanner, val s, ...);
void yybadtoken(parser_t *, int tok, val context);
-void end_of_regex(void *scanner);
-void end_of_char(void *scanner);
+void end_of_regex(scanner_t *scanner);
+void end_of_char(scanner_t *scanner);
int yylex_init(void **pscanner);
int yylex_destroy(void *scanner);
parser_t *yyget_extra(void *scanner);
diff --git a/parser.l b/parser.l
index d59955b7..d17b0c01 100644
--- a/parser.l
+++ b/parser.l
@@ -78,7 +78,7 @@ int yylex_destroy(void)
int yyget_column(void *);
void yyset_column (int column_no , yyscan_t yyscanner);
-void yyerror(void *scanner, parser_t *parser, const char *s)
+void yyerror(scanner_t *scanner, parser_t *parser, const char *s)
{
yyerrorf(scanner, lit("~a"), string_utf8(s), nao);
if (parser->prepared_msg) {
@@ -87,7 +87,7 @@ void yyerror(void *scanner, parser_t *parser, const char *s)
}
}
-void yyerrorf(void *scanner, val fmt, ...)
+void yyerrorf(scanner_t *scanner, val fmt, ...)
{
parser_t *parser = yyget_extra(scanner);
@@ -137,7 +137,7 @@ static wchar_t char_esc(int letter)
internal_error("unhandled escape character");
}
-static wchar_t num_esc(void *scn, char *num)
+static wchar_t num_esc(scanner_t *scn, char *num)
{
if (num[0] == 'x') {
if (strlen(num) > 7)
@@ -280,7 +280,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
<NESTED>({FLO}|{FLODOT}){NTOK} {
val str = string_utf8(yytext);
- yyerrorf(yyscanner, lit("trailing junk in floating-point literal: ~a"), str, nao);
+ yyerrorf(yyg, lit("trailing junk in floating-point literal: ~a"), str, nao);
if (yy_top_state(yyscanner) == INITIAL
|| yy_top_state(yyscanner) == QSILIT
@@ -673,7 +673,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
<SPECIAL>[\\](x{HEX}+|{OCT}+) {
wchar_t lexeme[2];
- lexeme[0] = num_esc(yyscanner, yytext + 1);
+ lexeme[0] = num_esc(yyg, yytext + 1);
lexeme[1] = 0;
yylval->lexeme = chk_strdup(lexeme);
yy_pop_state(yyscanner);
@@ -681,7 +681,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
}
<SPECIAL>[\\]. {
- yyerrorf(yyscanner, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao);
+ yyerrorf(yyg, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao);
}
<SPECIAL,QSPECIAL,NESTED,BRACED>[;].* {
@@ -712,7 +712,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
}
<REGEX>[\\](x{HEX}+|{OCT}+);? {
- yylval->chr = num_esc(yyscanner, yytext + 1);
+ yylval->chr = num_esc(yyg, yytext + 1);
return REGCHAR;
}
@@ -833,16 +833,16 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
}
<STRLIT,QSILIT,WLIT,QWLIT>[\\](x{HEX}+|{OCT}+);? {
- yylval->chr = num_esc(yyscanner, yytext+1);
+ yylval->chr = num_esc(yyg, yytext+1);
return LITCHAR;
}
<STRLIT,QSILIT,WLIT,QWLIT>[\\]. {
- yyerrorf(yyscanner, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao);
+ yyerrorf(yyg, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao);
}
<CHRLIT>(x{HEX}+|o{OCT}+) {
- yylval->chr = num_esc(yyscanner, yytext);
+ yylval->chr = num_esc(yyg, yytext);
return LITCHAR;
}
@@ -905,31 +905,27 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
%%
-void end_of_regex(yyscan_t yyscanner)
+void end_of_regex(scanner_t *yyg)
{
- struct yyguts_t *yyg = (struct yyguts_t *) yyscanner;
-
if (YYSTATE != REGEX)
internal_error("end_of_regex called in wrong scanner state");
- yy_pop_state(yyscanner);
+ yy_pop_state(yyg);
if (YYSTATE != INITIAL) {
- if (yy_top_state(yyscanner) == INITIAL
- || yy_top_state(yyscanner) == QSILIT
- || yy_top_state(yyscanner) == QWLIT)
- yy_pop_state(yyscanner);
+ if (yy_top_state(yyg) == INITIAL
+ || yy_top_state(yyg) == QSILIT
+ || yy_top_state(yyg) == QWLIT)
+ yy_pop_state(yyg);
}
}
-void end_of_char(yyscan_t yyscanner)
+void end_of_char(scanner_t *yyg)
{
- struct yyguts_t *yyg = (struct yyguts_t *) yyscanner;
-
if (YYSTATE != CHRLIT)
internal_error("end_of_char called in wrong scanner state");
- yy_pop_state(yyscanner);
+ yy_pop_state(yyg);
}
val source_loc(val form)
diff --git a/parser.y b/parser.y
index 00bb15cf..fb2ff6ea 100644
--- a/parser.y
+++ b/parser.y
@@ -47,7 +47,7 @@
#include "stream.h"
#include "parser.h"
-static val sym_helper(void *scnr, wchar_t *lexeme, val meta_allowed);
+static val sym_helper(scanner_t *scnr, wchar_t *lexeme, val meta_allowed);
static val repeat_rep_helper(val sym, val args, val main, val parts);
static val define_transform(parser_t *parser, val define_form);
static val lit_char_helper(val litchars);
@@ -72,7 +72,7 @@ int yylex(union YYSTYPE *, void *scanner);
%}
%pure-parser
-%parse-param{void *scnr}
+%parse-param{scanner_t *scnr}
%parse-param{parser_t *parser}
%lex-param{void *scnr}
@@ -986,7 +986,7 @@ int yylex(YYSTYPE *, void *scanner);
val rlcp(val to, val from);
#endif
-static val sym_helper(void *scnr, wchar_t *lexeme, val meta_allowed)
+static val sym_helper(scanner_t *scnr, wchar_t *lexeme, val meta_allowed)
{
int leading_at = *lexeme == L'@';
wchar_t *tokfree = lexeme;
@@ -1081,7 +1081,7 @@ static val repeat_rep_helper(val sym, val args, val main, val parts)
static val define_transform(parser_t *parser, val define_form)
{
- void *scnr = parser->scanner;
+ scanner_t *scnr = parser->scanner;
val sym = first(define_form);
val args = second(define_form);
@@ -1280,7 +1280,7 @@ static val make_expr(parser_t *parser, val sym, val rest, val lineno)
void yybadtoken(parser_t *parser, int tok, val context)
{
val problem = nil;
- void *scnr = parser->scanner;
+ scanner_t *scnr = parser->scanner;
switch (tok) {
case ERRTOK:
@@ -1354,6 +1354,7 @@ void yybadtoken(parser_t *parser, int tok, val context)
int parse(val stream, val name, parser_t *parser)
{
int res;
+ void *scanner;
parser->lineno = 1;
parser->errors = 0;
@@ -1361,7 +1362,8 @@ int parse(val stream, val name, parser_t *parser)
parser->name = name;
parser->prepared_msg = nil;
parser->syntax_tree = nil;
- yylex_init(&parser->scanner);
+ yylex_init(&scanner);
+ parser->scanner = (scanner_t *) scanner;
yyset_extra(parser, parser->scanner);