From 8b46bbb1c0b3aefea7fa683b53165e497a14056d Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 7 Jan 2013 13:29:05 -0600 Subject: [PATCH] Change substring index notation to use a colon (addresses #422). String slice notation is written as `s[1:2]` instead of `s[1, 2]` because the later is ambiguous with composite index types. --- src/Expr.cc | 16 +++++++++++++- src/Expr.h | 2 +- src/parse.y | 8 +++++++ testing/btest/core/leaks/string-indexing.bro | 22 ++++++++++---------- testing/btest/language/string-indexing.bro | 22 ++++++++++---------- 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index eef0e7b69e..b3127d6a7f 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2801,12 +2801,26 @@ bool AssignExpr::DoUnserialize(UnserialInfo* info) return UNSERIALIZE(&is_init); } -IndexExpr::IndexExpr(Expr* arg_op1, ListExpr* arg_op2) +IndexExpr::IndexExpr(Expr* arg_op1, ListExpr* arg_op2, bool is_string_slice) : BinaryExpr(EXPR_INDEX, arg_op1, arg_op2) { if ( IsError() ) return; + if ( is_string_slice ) + { + if ( ! IsString(op1->Type()->Tag()) ) + ExprError("slice notation indexing can apply only to strings"); + } + else if ( IsString(op1->Type()->Tag()) ) + { + if ( arg_op2->Exprs().length() != 1 ) + ExprError("invalid string index expression"); + } + + if ( IsError() ) + return; + int match_type = op1->Type()->MatchesIndex(arg_op2); if ( match_type == DOES_NOT_MATCH_INDEX ) SetError("not an index type"); diff --git a/src/Expr.h b/src/Expr.h index ea17c735b5..ac3ab0f4f2 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -646,7 +646,7 @@ protected: class IndexExpr : public BinaryExpr { public: - IndexExpr(Expr* op1, ListExpr* op2); + IndexExpr(Expr* op1, ListExpr* op2, bool is_string_slice = false); int CanAdd() const; int CanDel() const; diff --git a/src/parse.y b/src/parse.y index a16b742728..090786647e 100644 --- a/src/parse.y +++ b/src/parse.y @@ -418,6 +418,14 @@ expr: $$ = new IndexExpr($1, $3); } + | expr '[' expr ':' expr ']' + { + set_location(@1, @6); + ListExpr* le = new ListExpr($3); + le->Append($5); + $$ = new IndexExpr($1, le, true); + } + | expr '$' TOK_ID { set_location(@1, @3); diff --git a/testing/btest/core/leaks/string-indexing.bro b/testing/btest/core/leaks/string-indexing.bro index 40af2317e6..f9ea000ef9 100644 --- a/testing/btest/core/leaks/string-indexing.bro +++ b/testing/btest/core/leaks/string-indexing.bro @@ -11,16 +11,16 @@ event new_connection(c: connection) { local s = "0123456789"; print s[1]; - print s[1,2]; - print s[1,6]; - print s[0,20]; + print s[1:2]; + print s[1:6]; + print s[0:20]; print s[-2]; - print s[-3,-1]; - print s[-1,-10]; - print s[-1,0]; - print s[-1,5]; - print s[20, 23]; - print s[-20, 23]; - print s[0,5][2]; - print s[0,5][1,3][0]; + print s[-3:1]; + print s[-1:10]; + print s[-1:0]; + print s[-1:5]; + print s[20:23]; + print s[-20:23]; + print s[0:5][2]; + print s[0:5][1:3][0]; } diff --git a/testing/btest/language/string-indexing.bro b/testing/btest/language/string-indexing.bro index d05c1b6c5e..f991b3c5fa 100644 --- a/testing/btest/language/string-indexing.bro +++ b/testing/btest/language/string-indexing.bro @@ -3,15 +3,15 @@ local s = "0123456789"; print s[1]; -print s[1,2]; -print s[1,6]; -print s[0,20]; +print s[1:2]; +print s[1:6]; +print s[0:20]; print s[-2]; -print s[-3,-1]; -print s[-1,-10]; -print s[-1,0]; -print s[-1,5]; -print s[20, 23]; -print s[-20, 23]; -print s[0,5][2]; -print s[0,5][1,3][0]; +print s[-3:-1]; +print s[-1:-10]; +print s[-1:0]; +print s[-1:5]; +print s[20:23]; +print s[-20:23]; +print s[0:5][2]; +print s[0:5][1:3][0];