Branch: refs/heads/master Author: Adam Hirst adam@aphirst.karoo.co.uk Committer: Colomban Wendling ban@herbesfolles.org Date: Sat, 15 Feb 2014 14:48:31 UTC Commit: 1c0fa99e1d84b0331d65e56dcab4002f0006ccb1 https://github.com/geany/geany/commit/1c0fa99e1d84b0331d65e56dcab4002f0006cc...
Log Message: ----------- Support F2003 array syntax and F2008 coarrays
Fortran 2003 allows '[' and ']' as array constructors in addition to the legacy '(/' and '/)'. Fortran 2008 allows '[]' as part of a CODIMENSION specifier, which can either be `codimension[]` in the type-spec; or as either `variable[]` or `variable()[]` in the entry-spec.
Credit to Colomban Wendling for the skipOverSquares logic, and treating `codimension` as a special-case.
Last part of bug #1023.
Modified Paths: -------------- tagmanager/ctags/fortran.c tests/ctags/Makefile.am tests/ctags/square_parens.f90 tests/ctags/square_parens.f90.tags
Modified: tagmanager/ctags/fortran.c 49 files changed, 38 insertions(+), 11 deletions(-) =================================================================== @@ -70,6 +70,7 @@ KEYWORD_cexternal, KEYWORD_cglobal, KEYWORD_character, + KEYWORD_codimension, KEYWORD_common, KEYWORD_complex, KEYWORD_contains, @@ -154,6 +155,8 @@ TOKEN_OPERATOR, TOKEN_PAREN_CLOSE, TOKEN_PAREN_OPEN, + TOKEN_SQUARE_CLOSE, + TOKEN_SQUARE_OPEN, TOKEN_PERCENT, TOKEN_STATEMENT_END, TOKEN_STRING @@ -238,6 +241,7 @@ { "cexternal", KEYWORD_cexternal }, { "cglobal", KEYWORD_cglobal }, { "character", KEYWORD_character }, + { "codimension", KEYWORD_codimension }, { "common", KEYWORD_common }, { "complex", KEYWORD_complex }, { "contains", KEYWORD_contains }, @@ -964,10 +968,12 @@ static void readToken (tokenInfo *const token) case EOF: longjmp (Exception, (int) ExceptionEOF); break; case ' ': goto getNextChar; case '\t': goto getNextChar; - case ',': token->type = TOKEN_COMMA; break; - case '(': token->type = TOKEN_PAREN_OPEN; break; - case ')': token->type = TOKEN_PAREN_CLOSE; break; - case '%': token->type = TOKEN_PERCENT; break; + case ',': token->type = TOKEN_COMMA; break; + case '(': token->type = TOKEN_PAREN_OPEN; break; + case ')': token->type = TOKEN_PAREN_CLOSE; break; + case '[': token->type = TOKEN_SQUARE_OPEN; break; + case ']': token->type = TOKEN_SQUARE_CLOSE; break; + case '%': token->type = TOKEN_PERCENT; break;
case '*': case '/': @@ -1096,25 +1102,33 @@ static void skipToNextStatement (tokenInfo *const token) } while (isType (token, TOKEN_STATEMENT_END)); }
-/* skip over parenthesis enclosed contents starting at next token. - * Token is left at the first token following closing parenthesis. If an - * opening parenthesis is not found, `token' is moved to the end of the - * statement. +/* skip over paired tokens, managing nested pairs and stopping at statement end + * or right after closing token, whatever comes first. */ -static void skipOverParens (tokenInfo *const token) +static void skipOverPair (tokenInfo *const token, tokenType topen, tokenType tclose) { int level = 0; do { if (isType (token, TOKEN_STATEMENT_END)) break; - else if (isType (token, TOKEN_PAREN_OPEN)) + else if (isType (token, topen)) ++level; - else if (isType (token, TOKEN_PAREN_CLOSE)) + else if (isType (token, tclose)) --level; readToken (token); } while (level > 0); }
+static void skipOverParens (tokenInfo *const token) +{ + skipOverPair (token, TOKEN_PAREN_OPEN, TOKEN_PAREN_CLOSE); +} + +static void skipOverSquares (tokenInfo *const token) +{ + skipOverPair (token, TOKEN_SQUARE_OPEN, TOKEN_SQUARE_CLOSE); +} + static boolean isTypeSpec (tokenInfo *const token) { boolean result; @@ -1292,6 +1306,11 @@ static void parseQualifierSpecList (tokenInfo *const token) readToken (token); break;
+ case KEYWORD_codimension: + readToken (token); + skipOverSquares (token); + break; + case KEYWORD_dimension: case KEYWORD_extends: case KEYWORD_intent: @@ -1329,8 +1348,13 @@ static void parseEntityDecl (tokenInfo *const token) Assert (isType (token, TOKEN_IDENTIFIER)); makeFortranTag (token, variableTagType ()); readToken (token); + /* we check for both '()' and '[]' + * coarray syntax permits variable(), variable[], or variable()[] + */ if (isType (token, TOKEN_PAREN_OPEN)) skipOverParens (token); + if (isType (token, TOKEN_SQUARE_OPEN)) + skipOverSquares (token); if (isType (token, TOKEN_OPERATOR) && strcmp (vStringValue (token->string), "*") == 0) { @@ -1353,8 +1377,11 @@ static void parseEntityDecl (tokenInfo *const token) ! isType (token, TOKEN_STATEMENT_END)) { readToken (token); + /* another coarray check, for () and [] */ if (isType (token, TOKEN_PAREN_OPEN)) skipOverParens (token); + if (isType (token, TOKEN_SQUARE_OPEN)) + skipOverSquares (token); } } }
Modified: tests/ctags/Makefile.am 1 files changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -222,6 +222,7 @@ test_sources = \ simple.tcl \ spurious_label_tags.c \ sql_single_quote.sql \ + square_parens.f90 \ state_machine.v \ static_array.c \ stdcall.f \
Modified: tests/ctags/square_parens.f90 39 files changed, 39 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,39 @@ +module squaretest + implicit none + + type Symmetry + integer :: matrix(3,3), iterations + end type Symmetry + + + ! make sure F2003 '[]' arrays don't break the symbol list + type(Symmetry), parameter :: symmetries(14) = & + [ Symmetry(reshape([1,0,0, 0,1,0, 0,0,1], [3,3]),1), & + Symmetry(reshape([1,0,0, 0,0,1, 0,-1,0],[3,3]),3), & + Symmetry(reshape([0,0,-1, 0,1,0, 1,0,0], [3,3]),3) ] + integer :: invisible + + ! make sure coarray syntax doesn't break the symbol list + real, allocatable :: state(:)[:] + integer :: invisible_two + + ! there are multiple ways to specify `dimension` and `codimension` + ! a normal dimension and a codimension + real, intent(in), allocatable, dimension(:), codimension[:] :: state_two + integer :: invisible_three + + ! a 'normal' scalar (no '()'), but with a codimension '[]' + real, allocatable :: assignee[:] + integer :: invisible_four + +contains + + subroutine execute(state) + real, intent(in) :: state(:)[:] + end subroutine execute + +end module squaretest + +program main + use module squaretest +end program main
Modified: tests/ctags/square_parens.f90.tags 13 files changed, 13 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,13 @@ +# format=tagmanager +SymmetryĚ4096ÎsquaretestÖ0 +assigneeĚ16384ÎsquaretestÖ0 +executeĚ64ÎsquaretestÖ0 +invisibleĚ16384ÎsquaretestÖ0 +invisible_fourĚ16384ÎsquaretestÖ0 +invisible_threeĚ16384ÎsquaretestÖ0 +invisible_twoĚ16384ÎsquaretestÖ0 +mainĚ512Ö0 +squaretestĚ256Ö0 +stateĚ16384ÎsquaretestÖ0 +state_twoĚ16384ÎsquaretestÖ0 +symmetriesĚ16384ÎsquaretestÖ0
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).