--
-- Syntax Highlighting for C/C++
--



--
-- Require our helper-library
--
local lpeg_utils = require( "lpeg_utils" )


--
-- This file is a Lua module.
--
local mymodule = {}

--
-- The result we return to the caller.
--
local retval = ""

--
-- Helper to add the colour.
--
function add( colour, str )
   length = string.len(str)
   while( length >0 ) do
      retval = retval .. string.char( colour )
      length = length -1
   end
end

--
-- Shorten our references.
--
local P = lpeg.P
local R = lpeg.R
local S = lpeg.S
local C = lpeg.C



--
-- Numbers
--
local numbers = lpeg_utils.numbers() / function(...) add(YELLOW, ... ) end


--
-- Character-strings
--
local charlit   = P'L'^-1 * P"'" * (P'\\' * P(1) + (1 - S"\\'"))^1 * P"'"
local stringlit = P'L'^-1 * P'"' * (P'\\' * P(1) + (1 - S'\\"'))^0 * P'"'
local strings   = (charlit + stringlit) / function(...) add(BLUE, ... ) end


--
-- Single and multi-line comments.
--
local ccomment   = P'/*' * (1 - P'*/')^0 * P'*/'
local newcomment = P'//' * (1 - P'\n')^0
local comment    = (ccomment + newcomment) / function(...)  add(RED, ... ) end

--
-- Show trailing-whitespace with a `cyan` background.
--
local trailing_space = S' \t'^1 * S'\n'/ function(...) add(REV_CYAN,... ) end

--
-- Literals
--
local literal = ( charlit + stringlit) / function(...) add(BLUE, ... ) end

--
-- Keywords
--
local keyword = lpeg_utils.tokens({
                                     "auto",
                                     "bool",
                                     "break",
                                     "case",
                                     "char",
                                     "const",
                                     "continue",
                                     "default",
                                     "do",
                                     "double",
                                     "else",
                                     "enum",
                                     "extern",
                                     "float",
                                     "for",
                                     "goto",
                                     "if",
                                     "inline",
                                     "int",
                                     "long",
                                     "register",
                                     "restrict",
                                     "return",
                                     "short",
                                     "signed",
                                     "sizeof",
                                     "static",
                                     "struct",
                                     "switch",
                                     "typedef",
                                     "union",
                                     "unsigned",
                                     "void",
                                     "volatile",
                                     "while"
                                  } ) / function(...) add(CYAN, ... ) end

--
-- Functions :
--   TODO: Add more
--
local functions = lpeg_utils.tokens({
                                       "stderr",
                                       "stdout",
                                       "printf",
                                       "strlen",
                                       "wcslen",
                                       "malloc",
                                       "free",
                                       "delete",
                                       "new",
                                       "fprintf",
                                       "vsnprintf",
                                       "strcpy",
                                       "strncpy",
                                       "sprintf",
                                       "getenv",
                                       "ioctl"
                                    } ) / function(...) add(GREEN, ... ) end


--
-- Match any single character
--
local any = C(P(1) )/ function(...) add(WHITE,... ) end



--
-- The complete set of tokens we understand
--
local tokens = (comment + functions + keyword + numbers + strings + trailing_space + any)^0


--
-- The function we export.
--
function mymodule.parse(input)
   retval = ""
   lpeg.match(tokens, input)
   return( retval )
end

--
-- Export ourself
--
return mymodule
