From 35e3ffb2a6e531405cb9461995ebd69c3f969a39 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 27 Aug 2018 23:11:34 +0200 Subject: [PATCH] kernel: catch some invalid uses of '~'; add tests Also, print a (more) helpful error message. Before: gap> ~; Error, '~' does not have a value here not in any function at *stdin*:1 gap> x -> ~; function( x ) ... end gap> x -> (1,~); function( x ) ... end gap> (1,~); Error, '~' does not have a value here not in any function at *stdin*:4 After: gap> ~; Syntax error: '~' not allowed here ~; ^ gap> x -> ~; Syntax error: '~' not allowed here x -> ~; ^ gap> x -> (1,~); Syntax error: '~' not allowed here x -> (1,~); ^ gap> (1,~); Syntax error: '~' not allowed here (1,~); ^ --- src/read.c | 5 ++- tst/testinstall/interpreter.tst | 6 --- tst/testinstall/tilde.tst | 73 +++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/read.c b/src/read.c index b4d9cc3363..c3fc2c3e59 100644 --- a/src/read.c +++ b/src/read.c @@ -1235,7 +1235,7 @@ static void ReadFuncExprBody( // push the new local variables list PushPlist(STATE(StackNams), args.nams); - // begin interpreting the function expression (with 1 argument) + // begin interpreting the function expression TRY_IF_NO_ERROR { IntrFuncExprBegin(args.isvarg ? -args.narg : args.narg, nloc, args.nams, startLine); @@ -1477,6 +1477,9 @@ static void ReadLiteral ( /* '~' */ case S_TILDE: + if (ReaderState()->ReadTop == 0) { + SyntaxError("'~' not allowed here"); + } ReaderState()->ReadTilde = 1; TRY_IF_NO_ERROR { IntrTildeExpr(); } Match( S_TILDE, "~", follow ); diff --git a/tst/testinstall/interpreter.tst b/tst/testinstall/interpreter.tst index db97b54c1c..c3becf8592 100644 --- a/tst/testinstall/interpreter.tst +++ b/tst/testinstall/interpreter.tst @@ -39,12 +39,6 @@ gap> QUIT; gap> ?qwert_asdf Help: no matching entry found -# -# tilde -# -gap> ~; -Error, '~' does not have a value here - # # function call with options # diff --git a/tst/testinstall/tilde.tst b/tst/testinstall/tilde.tst index df2b79b14d..73ee56afba 100644 --- a/tst/testinstall/tilde.tst +++ b/tst/testinstall/tilde.tst @@ -1,9 +1,13 @@ gap> START_TEST("tilde.tst"); + +# gap> aqq~ := 1; Error, Variable: 'aqq' must have a value Syntax error: ; expected in stream:1 aqq~ := 1; ^ + +# gap> l := [2, ~]; [ 2, ~ ] gap> l = l[2]; @@ -18,6 +22,71 @@ gap> r.x; rec( x := ~, y := [ 1, 2, ~ ] ) gap> r.y[3]; rec( x := ~, y := [ 1, 2, ~ ] ) + +# +gap> [ ~ ]; +[ ~ ] +gap> [ 1, 2, [0 .. Length(~)] ]; +[ 1, 2, [ 0 .. 2 ] ] +gap> [0, 1 + ~, 2 ]; +[ 0, [ 1 ], 2 ] + +# +gap> [ (x->~)(1) ]; +[ ~ ] +gap> l := [ x->~ ]; # this function escapes with an invalid tilde reference +[ function( x ) ... end ] +gap> f := l[1];; +gap> f(1); +Error, '~' does not have a value here +gap> [ f(1) ]; +[ ~ ] + +# +gap> ~; +Syntax error: '~' not allowed here in stream:1 +~; +^ +gap> (1,~); +Syntax error: '~' not allowed here in stream:1 +(1,~); + ^ +gap> x->~; +Syntax error: '~' not allowed here in stream:1 +x->~; + ^ +gap> x -> (1,~); +Syntax error: '~' not allowed here in stream:1 +x -> (1,~); + ^ + +# +gap> [1..~]; +Syntax error: Sorry, '~' not allowed in range in stream:1 +[1..~]; + ^ +gap> [~..1]; +Syntax error: Sorry, '~' not allowed in range in stream:1 +[~..1]; + ^ +gap> [1,~..5]; +Syntax error: Sorry, '~' not allowed in range in stream:1 +[1,~..5]; + ^ +gap> x->[1..~]; +Syntax error: Sorry, '~' not allowed in range in stream:1 +x->[1..~]; + ^ +gap> x->[~..1]; +Syntax error: Sorry, '~' not allowed in range in stream:1 +x->[~..1]; + ^ +gap> x->[1,~..5]; +Syntax error: Sorry, '~' not allowed in range in stream:1 +x->[1,~..5]; + ^ + +# gap> f := function(~) local a; end; Syntax error: identifier expected in stream:1 f := function(~) local a; end; @@ -42,6 +111,8 @@ gap> {~,~} -> 2; Syntax error: identifier expected in stream:1 {~,~} -> 2; ^ + +# gap> list1 := [1,~]; [ 1, ~ ] gap> list2 := [1,[1,[1,[1,0]]]]; @@ -96,4 +167,6 @@ gap> [2,rem(~),3,4,rem(~),5,6,rem(~)]; [ , 1, 3,, 1, 5,, 1 ] gap> (function() return [2,rem(~),3,4,rem(~),5,6,rem(~)]; end)(); [ , 1, 3,, 1, 5,, 1 ] + +# gap> STOP_TEST( "tilde.tst", 1);