\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{listings}
\usepackage{inconsolata}

\definecolor{basicCol}{HTML}{000000}
\definecolor{commentCol}{HTML}{000000}
\definecolor{stringCol}{HTML}{000000}
\definecolor{keywordCol}{HTML}{000000}
\definecolor{identifierCol}{HTML}{000000}

% from https://gist.github.com/nikolajquorning/92bbbeef32e1dd80105c9bf2daceb89a
\lstdefinelanguage{sml} {
  morekeywords= {
    EQUAL, GREATER, LESS, NONE, SOME, abstraction, abstype, and, andalso, array, as, before, bool, case, char, datatype, do, else, end, eqtype, exception, exn, false, fn, fun, functor, handle, if, in, include, infix, infixr, int, let, list, local, nil, nonfix, not, o, of, op, open, option, orelse, overload, print, raise, real, rec, ref, sharing, sig, signature, string, struct, structure, substring, then, true, type, unit, val, vector, where, while, with, withtype, word
  },
  morestring=[b]",
  morecomment=[s]{(*}{*)},
}

\lstdefinelanguage{D}{
  % Keywords
  morekeywords=[1]{
    abstract, alias, align, auto, body, break, cast, catch, class, const,
    continue, debug, delegate, delete, deprecated, do, else, enum, export,
    false, final, finally, for, foreach, foreach_reverse, function, goto, if,
    immutable, import, in, inout, interface, invariant, is, lazy, macro, mixin,
    module, new, nothrow, null, out, override, package, pragma, private,
    protected, public, pure, ref, return, shared, static, struct, super,
    switch, synchronized, template, this, throw, true, try, typedef, typeid,
    typeof, union, unittest, volatile, while, with
  },
  % Special identifiers, common functions
  morekeywords=[2]{enforce},
  % Ugly identifiers
  morekeywords=[3]{
    __DATE__, __EOF__, __FILE__, __LINE__, __TIMESTAMP__, __TIME__, __VENDOR__,
    __VERSION__, __ctfe, __gshared, __monitor, __thread, __vptr, _argptr,
    _arguments, _ctor, _dtor
  },
  % Basic types
  morekeywords=[4]{
     byte, ubyte, short, ushort, int, uint, long, ulong, cent, ucent, void,
     bool, bit, float, double, real, ushort, int, uint, long, ulong, float,
     char, wchar, dchar, string, wstring, dstring, ireal, ifloat, idouble,
     creal, cfloat, cdouble, size_t, ptrdiff_t, sizediff_t, equals_t, hash_t
  },
  % Strings
  morestring=[b]{"},
  morestring=[b]{'},
  morestring=[b]{`},
  % Comments
  comment=[l]{//},
  morecomment=[s]{/*}{*/},
  morecomment=[s][\color{blue}]{/**}{*/},
  morecomment=[n]{/+}{+/},
  morecomment=[n][\color{blue}]{/++}{+/},
  % Options
  sensitive=true
}

\lstdefinelanguage{rust}{
  % Keywords
  morekeywords=[1]{
    abstract, alignof, as, become, box,
    break, const, continue, crate, do,
    else, enum, extern, false, final,
    fn, for, if, impl, in,
    let, loop, macro, match, mod,
    move, mut, offsetof, override, priv,
    proc, pub, pure, ref, return,
    Self, self, sizeof, static, struct,
    super, trait, true,  type, typeof,
    unsafe, unsized, use, virtual, where,
    while, yield
  },
  % Strings
  morestring=[b]{"},
  % Comments
  comment=[l]{//},
  morecomment=[s]{/*}{*/},
  % Options
  sensitive=true
}

\lstdefinelanguage{pseudo}{
	morekeywords={string,uint,int,bool,float},%
	sensitive=true,%
	morecomment=[l]{//},%
	morecomment=[s]{/*}{*/},%
	morestring=[b]',%
	morestring=[b]",%
	morestring=[s]{`}{`},%
}%

\newcommand{\KWC}{K-W C\xspace}

\lstdefinestyle{pseudoStyle}{
  escapeinside={@@},
  basicstyle=\linespread{0.9}\sf\footnotesize,		% reduce line spacing and use typewriter font
  keywordstyle=\bfseries\color{blue},
  keywordstyle=[2]\bfseries\color{Plum},
  commentstyle=\itshape\color{OliveGreen},		    % green and italic comments
  identifierstyle=\color{identifierCol},
  stringstyle=\sf\color{Mahogany},			          % use sanserif font
  mathescape=true,
  columns=fixed,
  aboveskip=4pt,                                  % spacing above/below code block
  belowskip=3pt,
  keepspaces=true,
  tabsize=4,
  % frame=lines,
  literate=,
  showlines=true,                                 % show blank lines at end of code
  showspaces=false,
  showstringspaces=false,
  escapechar=\$,
  xleftmargin=\parindentlnth,                     % indent code to paragraph indentation
  moredelim=[is][\color{red}\bfseries]{**R**}{**R**},    % red highlighting
  % moredelim=* detects keywords, comments, strings, and other delimiters and applies their formatting
  % moredelim=** allows cumulative application
}

\lstdefinestyle{defaultStyle}{
  escapeinside={@@},
  basicstyle=\linespread{0.9}\tt\footnotesize,		% reduce line spacing and use typewriter font
  keywordstyle=\bfseries\color{blue},
  keywordstyle=[2]\bfseries\color{Plum},
  commentstyle=\itshape\color{OliveGreen},		    % green and italic comments
  identifierstyle=\color{identifierCol},
  stringstyle=\sf\color{Mahogany},			          % use sanserif font
  mathescape=true,
  columns=fixed,
  aboveskip=4pt,                                  % spacing above/below code block
  belowskip=3pt,
  keepspaces=true,
  tabsize=4,
  % frame=lines,
  literate=,
  showlines=true,                                 % show blank lines at end of code
  showspaces=false,
  showstringspaces=false,
  escapechar=\$,
  xleftmargin=\parindentlnth,                     % indent code to paragraph indentation
  moredelim=[is][\color{red}\bfseries]{**R**}{**R**},    % red highlighting
  % moredelim=* detects keywords, comments, strings, and other delimiters and applies their formatting
  % moredelim=** allows cumulative application
}

\lstdefinestyle{cfaStyle}{
  escapeinside={@@},
  basicstyle=\linespread{0.9}\tt\footnotesize,		% reduce line spacing and use typewriter font
  keywordstyle=\bfseries\color{blue},
  keywordstyle=[2]\bfseries\color{Plum},
  commentstyle=\sf\itshape\color{OliveGreen},		  % green and italic comments
  identifierstyle=\color{identifierCol},
  stringstyle=\sf\color{Mahogany},			          % use sanserif font
  mathescape=true,
  columns=fixed,
  aboveskip=4pt,                                  % spacing above/below code block
  belowskip=3pt,
  keepspaces=true,
  tabsize=4,
  % frame=lines,
  literate=,
  showlines=true,                                 % show blank lines at end of code
  showspaces=false,
  showstringspaces=false,
  escapechar=\$,
  xleftmargin=\parindentlnth,                     % indent code to paragraph indentation
  moredelim=[is][\color{red}\bfseries]{**R**}{**R**},    % red highlighting
  morekeywords=[2]{accept, signal, signal_block, wait, waitfor},
}

\lstMakeShortInline[basewidth=0.5em,breaklines=true,basicstyle=\normalsize\ttfamily\color{basicCol}]@  % single-character for \lstinline

\lstnewenvironment{ccode}[1][]{
  \lstset{
    language = C,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{cfacode}[1][]{
  \lstset{
    language = CFA,
    style=cfaStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{pseudo}[1][]{
  \lstset{
    language = pseudo,
    style=pseudoStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{cppcode}[1][]{
  \lstset{
    language = c++,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{ucppcode}[1][]{
  \lstset{
    language = c++,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{javacode}[1][]{
  \lstset{
    language = java,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{scalacode}[1][]{
  \lstset{
    language = scala,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{smlcode}[1][]{
  \lstset{
    language = sml,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{dcode}[1][]{
  \lstset{
    language = D,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{rustcode}[1][]{
  \lstset{
    language = rust,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\lstnewenvironment{gocode}[1][]{
  \lstset{
    language = Golang,
    style=defaultStyle,
    captionpos=b,
    #1
  }
}{}

\newcommand{\zero}{\lstinline{zero_t}\xspace}
\newcommand{\one}{\lstinline{one_t}\xspace}
\newcommand{\ateq}{\lstinline{\@=}\xspace}
\newcommand{\code}[1]{\lstinline[language=CFA,style=cfaStyle]{#1}}
\newcommand{\pscode}[1]{\lstinline[language=pseudo,style=pseudoStyle]{#1}}