[geany/geany] 1c0fa9: Support F2003 array syntax and F2008 coarrays

Adam Hirst git-noreply at xxxxx
Sat Feb 15 14:48:31 UTC 2014


Branch:      refs/heads/master
Author:      Adam Hirst <adam at aphirst.karoo.co.uk>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Sat, 15 Feb 2014 14:48:31 UTC
Commit:      1c0fa99e1d84b0331d65e56dcab4002f0006ccb1
             https://github.com/geany/geany/commit/1c0fa99e1d84b0331d65e56dcab4002f0006ccb1

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).


More information about the Commits mailing list