@@ -149,6 +149,113 @@ spec =
149149 resetSrcSpan (collectFixedTokens' Fortran77 " INTEGER IF" )
150150 `shouldBe` resetSrcSpan [TType u " integer" , TId u " if" , TEOF u]
151151
152+ describe " Fortran 77 Legacy" $ do
153+ it " lexes inline comments" $ do
154+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " integer foo ! bar" )
155+ `shouldBe` resetSrcSpan [TType u " integer" , TId u " foo" , TEOF u]
156+
157+ it " lexes continuation lines separated by comments" $ do
158+ let src = unlines [ " integer foo,"
159+ , " C hello"
160+ , " + bar"
161+ ]
162+ resetSrcSpan (collectFixedTokens' Fortran77Legacy src)
163+ `shouldBe` resetSrcSpan [TType u " integer" , TId u " foo" , TComma u, TId u " bar" , TNewline u, TEOF u]
164+ let src = unlines [ " integer foo, ! hello"
165+ , " + bar"
166+ ]
167+ resetSrcSpan (collectFixedTokens' Fortran77Legacy src)
168+ `shouldBe` resetSrcSpan [TType u " integer" , TId u " foo" , TComma u, TId u " bar" , TNewline u, TEOF u]
169+ let src = unlines [ " integer foo,"
170+ , " "
171+ , " + bar"
172+ ]
173+ resetSrcSpan (collectFixedTokens' Fortran77Legacy src)
174+ `shouldBe` resetSrcSpan [TType u " integer" , TId u " foo" , TComma u, TId u " bar" , TNewline u, TEOF u]
175+ let src = unlines [ " integer foo,"
176+ , " " -- the space is intentional
177+ , " + bar"
178+ ]
179+ resetSrcSpan (collectFixedTokens' Fortran77Legacy src)
180+ `shouldBe` resetSrcSpan [TType u " integer" , TId u " foo" , TComma u, TId u " bar" , TNewline u, TEOF u]
181+
182+ it " lexes the older TYPE statement" $ do
183+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " type *, 'hello'" )
184+ `shouldBe` resetSrcSpan [TTypePrint u, TStar u, TComma u, TString u " hello" , TEOF u]
185+
186+ it " lexes width-specific type declarations" $ do
187+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " integer*4 i" )
188+ `shouldBe` resetSrcSpan [TType u " integer" , TStar u, TInt u " 4" , TId u " i" , TEOF u]
189+
190+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " integer*4 function foo()" )
191+ `shouldBe` resetSrcSpan [TType u " integer" , TStar u, TInt u " 4" , TFunction u, TId u " foo" , TLeftPar u, TRightPar u, TEOF u]
192+
193+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " character*4 s" )
194+ `shouldBe` resetSrcSpan [TType u " character" , TStar u, TInt u " 4" , TId u " s" , TEOF u]
195+
196+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " character*(*) s" )
197+ `shouldBe` resetSrcSpan [TType u " character" , TStar u, TLeftPar u, TStar u, TRightPar u, TId u " s" , TEOF u]
198+
199+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " character s*(*)" )
200+ `shouldBe` resetSrcSpan [TType u " character" , TId u " s" , TStar u, TLeftPar u, TStar u, TRightPar u, TEOF u]
201+
202+ it " lexes strings case-sensitively" $ do
203+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " c = 'Hello'" )
204+ `shouldBe` resetSrcSpan [TId u " c" , TOpAssign u, TString u " Hello" , TEOF u]
205+
206+ it " lexes strings delimited by '\" '" $ do
207+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " c = \" hello\" " )
208+ `shouldBe` resetSrcSpan [TId u " c" , TOpAssign u, TString u " hello" , TEOF u]
209+
210+ it " lexes Hollerith constants" $ do
211+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " x = 7hmistral" )
212+ `shouldBe` resetSrcSpan [TId u " x" , TOpAssign u, THollerith u " mistral" , TEOF u]
213+
214+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " x = 7hshort\n " )
215+ `shouldBe` resetSrcSpan [TId u " x" , TOpAssign u, THollerith u " short " , TNewline u, TEOF u]
216+
217+ it " lexes BOZ constants" $ do
218+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " integer i, j, k / b'0101', o'0755', z'ab01' /" )
219+ `shouldBe` resetSrcSpan [ TType u " integer" , TId u " i" , TComma u, TId u " j" , TComma u, TId u" k"
220+ , TSlash u, TBozInt u " b'0101'" , TComma u, TBozInt u " o'0755'" , TComma u, TBozInt u " z'ab01'" , TSlash u
221+ , TEOF u ]
222+
223+ it " lexes non-standard identifiers" $ do
224+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " integer _this_is_a_long_identifier$" )
225+ `shouldBe` resetSrcSpan [TType u " integer" , TId u " _this_is_a_long_identifier$" , TEOF u]
226+
227+ it " lexes ';' as a line-terminator" $ do
228+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " integer i; integer j" )
229+ `shouldBe` resetSrcSpan [TType u " integer" , TId u " i" , TNewline u, TType u " integer" , TId u " j" , TEOF u]
230+
231+ it " lexes subscripts in assignments" $ do
232+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " x(0,0) = 0" )
233+ `shouldBe` resetSrcSpan [TId u " x" , TLeftPar u, TInt u " 0" , TComma u, TInt u " 0" , TRightPar u, TOpAssign u, TInt u " 0" , TEOF u]
234+
235+ it " lexes labeled DO WHILE blocks" $ do
236+ resetSrcSpan (collectFixedTokens' Fortran77Legacy " do 10 while (.true.)" )
237+ `shouldBe` resetSrcSpan [TDo u, TInt u " 10" , TWhile u, TLeftPar u, TBool u " .true." , TRightPar u, TEOF u]
238+
239+
240+ it " lexes structure/union/map blocks" $ do
241+ let src = unlines [ " structure /foo/"
242+ , " union"
243+ , " map"
244+ , " integer i"
245+ , " real r"
246+ , " end map"
247+ , " end union"
248+ , " end structure" ]
249+ resetSrcSpan (collectFixedTokens' Fortran77Legacy src)
250+ `shouldBe` resetSrcSpan [ TStructure u, TSlash u, TId u " foo" , TSlash u, TNewline u
251+ , TUnion u, TNewline u
252+ , TMap u, TNewline u
253+ , TType u " integer" , TId u " i" , TNewline u
254+ , TType u " real" , TId u " r" , TNewline u
255+ , TEndMap u, TNewline u
256+ , TEndUnion u, TNewline u
257+ , TEndStructure u, TNewline u
258+ , TEOF u ]
152259
153260example1 = unlines [
154261 " intEGerix" ,
0 commit comments