From 149d16d8fc9fb05ce250bd770a67606dfc9c7031 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 10 Oct 2019 19:00:49 -0400 Subject: [PATCH] add support for `line directive --- src/Language/SystemVerilog/Parser/Lex.x | 37 ++++++++++++++++++++++--- test/lex/file_line.sv | 7 +++++ test/lex/line.sv | 7 +++++ test/lex/line.v | 7 +++++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 test/lex/line.sv create mode 100644 test/lex/line.v diff --git a/src/Language/SystemVerilog/Parser/Lex.x b/src/Language/SystemVerilog/Parser/Lex.x index b709bc8..b46168d 100644 --- a/src/Language/SystemVerilog/Parser/Lex.x +++ b/src/Language/SystemVerilog/Parser/Lex.x @@ -529,12 +529,10 @@ lexFile includePaths env path = do where finalToks = coalesce $ reverse $ lsToks finalState where setEnv = do - -- standardize the file path format - path' <- includeSearch path modify $ \s -> s { lsEnv = env , lsIncludePaths = includePaths - , lsCurrFile = path' + , lsCurrFile = path } -- combines identifiers and numbers that cross macro boundaries @@ -716,6 +714,27 @@ takeQuotedString = do then lexicalError $ "library includes are not supported: " ++ res else return res +-- removes and returns a decimal number +takeNumber :: Alex Int +takeNumber = do + dropSpaces + leadCh <- peekChar + if '0' <= leadCh && leadCh <= '9' + then step 0 + else lexicalError $ "expected number, but found unexpected char: " + ++ show leadCh + where + step number = do + ch <- takeChar + if ch == ' ' || ch == '\n' then + return number + else if '0' <= ch && ch <= '9' then do + let digit = ord ch - ord '0' + step $ number * 10 + digit + else + lexicalError $ "unexpected char while reading number: " + ++ show ch + peekChar :: Alex Char peekChar = do (_, _, _, str) <- alexGetInput @@ -881,6 +900,16 @@ handleDirective (posOrig, _, _, strOrig) len = do modify $ push $ Token Lit_number tokStr tokPos alexMonadScan + "line" -> do + lineNumber <- takeNumber + quotedFilename <- takeQuotedString + _ <- takeNumber -- level, ignored + let filename = init $ tail quotedFilename + setCurrentFile filename + (AlexPn f _ c, prev, _, str) <- alexGetInput + alexSetInput (AlexPn f (lineNumber + 1) c, prev, [], str) + alexMonadScan + "include" -> do quotedFilename <- takeQuotedString inputFollow <- alexGetInput @@ -968,7 +997,7 @@ handleDirective (posOrig, _, _, strOrig) len = do currToks <- gets lsToks modify $ \s -> s { lsToks = [] } -- lex the macro expansion, preserving the file and line - alexSetInput (AlexPn 0 l 0, ' ' , [], replacement) + alexSetInput (AlexPn 0 l 0, ' ', [], replacement) alexMonadScan -- re-tag and save tokens from the macro expansion newToks <- gets lsToks diff --git a/test/lex/file_line.sv b/test/lex/file_line.sv index 2fc4164..ee119ed 100644 --- a/test/lex/file_line.sv +++ b/test/lex/file_line.sv @@ -1,3 +1,8 @@ +`ifndef INCLUDED +`define INCLUDED +`include "file_line.sv" +`else + `define MACRO(arg) $display(arg, `__FILE__, `__LINE__); `define MACRO_NO_ARG $display(`__FILE__, `__LINE__); module top; @@ -14,3 +19,5 @@ initial begin `MACRO("f") end endmodule + +`endif diff --git a/test/lex/line.sv b/test/lex/line.sv new file mode 100644 index 0000000..7cd0946 --- /dev/null +++ b/test/lex/line.sv @@ -0,0 +1,7 @@ +module top; + initial begin + $display(`__FILE__, `__LINE__); +`line 101 "fake.v" 1 + $display(`__FILE__, `__LINE__); + end +endmodule diff --git a/test/lex/line.v b/test/lex/line.v new file mode 100644 index 0000000..0e5df5c --- /dev/null +++ b/test/lex/line.v @@ -0,0 +1,7 @@ +module top; + initial begin + $display("line.sv", `__LINE__); + ; + $display("fake.v", 102); + end +endmodule