From 18dd42f65e620326bb21ffcde92004cc9705cbf8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 1 Nov 2015 19:18:57 -0800 Subject: New range type, distinct from cons cell. * eval.c (eval_init): Register intrinsic functions rcons, rangep from and to. (eval_init): Register rangep intrinsic. * gc.c (mark_obj): Traverse RNG objects. (finalize): Handle RNG in switch. * hash.c (equal_hash, eql_hash): Hashing for for RNG objects. * lib.c (range_s, rcons_s): New symbol variables. (code2type): Handle RNG type. (eql, equal): Equality for ranges. (less_tab_init): Table extended to cover RNG. (less): Semantics defined for ranges. (rcons, rangep, from, to): New functions. (obj_init): range_s and rcons_s variables initialized. (obj_print_impl): Produce #R notation for ranges. (generic_funcall, dwim_set): Recognize range objects for indexing * lib.h (enum type): New enum member, RNG. MAXTYPE redefined to RNG value. (TYPE_SHIFT): Increased to 5 since there are now 16 type codes. (struct range): New struct type. (union obj): New member rn, of type struct range. (range_s, rcons_s, rcons, rangep, from, to): Declared. (range_bind): New macro. * parser.l (grammar): New rule for recognizing the #R sequence as HASH_R token. * parser.y (HASH_R): New terminal symbol. (range): New nonterminal symbol. (n_expr): Derives the new range symbol. The n_expr DOTDOT n_expr rule produces rcons expression rather than const. * match.c (format_field): Recognize rcons syntax in fields which is now what ranges translate to. Also recognize range object. * tests/013/maze.tl (neigh): Fix code which destructures range as a cons. That can't be done any more. * txr.1: Document ranges. --- parser.y | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'parser.y') diff --git a/parser.y b/parser.y index 0208386d..d63eba4f 100644 --- a/parser.y +++ b/parser.y @@ -100,7 +100,7 @@ int yyparse(scanner_t *, parser_t *); %token UNTIL COLL OUTPUT REPEAT REP SINGLE FIRST LAST EMPTY %token MOD MODLAST DEFINE TRY CATCH FINALLY %token ERRTOK /* deliberately not used in grammar */ -%token HASH_BACKSLASH HASH_SLASH DOTDOT HASH_H HASH_S +%token HASH_BACKSLASH HASH_SLASH DOTDOT HASH_H HASH_S HASH_R %token WORDS WSPLICE QWORDS QWSPLICE %token SECRET_ESCAPE_R SECRET_ESCAPE_E @@ -116,7 +116,7 @@ int yyparse(scanner_t *, parser_t *); %type output_clause define_clause try_clause catch_clauses_opt %type if_clause elif_clauses_opt else_clause_opt %type line elems_opt elems clause_parts_h additional_parts_h -%type text texts elem var var_op modifiers vector hash struct +%type text texts elem var var_op modifiers vector hash struct range %type list exprs exprs_opt expr n_exprs r_exprs n_expr n_exprs_opt %type out_clauses out_clauses_opt out_clause %type repeat_clause repeat_parts_opt o_line @@ -737,6 +737,16 @@ struct : HASH_S list { if (unquotes_occur($2, 0)) $$ = rlcp(strct, num($1)); } } ; +range : HASH_R list { if (length($2) != two) + yyerr("range literal needs two elements"); + + if (unquotes_occur($2, 0)) + $$ = rlcp(cons(rcons_s, $2), num($1)); + else + { val range = rcons(first($2), second($2)); + $$ = rlcp(range, num($1)); } } + ; + list : '(' n_exprs ')' { $$ = rl($2, num($1)); } | '(' ')' { $$ = nil; } | '(' LAMBDOT n_expr ')' { $$ = $3; } @@ -818,6 +828,7 @@ n_expr : SYMTOK { $$ = symhlpr($1, t); } | vector { $$ = $1; } | hash { $$ = $1; } | struct { $$ = $1; } + | range { $$ = $1; } | lisp_regex { $$ = $1; } | chrlit { $$ = $1; } | strlit { $$ = $1; } @@ -833,7 +844,7 @@ n_expr : SYMTOK { $$ = symhlpr($1, t); } | SPLICE n_expr { $$ = rl(rlcp(list(sys_splice_s, $2, nao), $2), num(parser->lineno)); } | n_expr DOTDOT n_expr { uses_or2; - $$ = rlcp(list(cons_s, $1, $3, nao), + $$ = rlcp(list(rcons_s, $1, $3, nao), or2($1, $3)); } | n_expr '.' n_expr { uses_or2; if (consp($3) && car($3) == qref_s) { -- cgit v1.2.3