summary refs log blame commit diff stats
path: root/config/nimdoc.tex.cfg
blob: 599ede345a105dfbe382902b5e52bf256ed089d1 (plain) (tree)
1
2
3

                                                                           
                        
































































































                                                                                                                                               
                                    





















                                           
# This is the config file for the documentation generator that produces TeX
# output.
# (c) 2012 Andreas Rumpf
# Feel free to edit the templates as you need.

split.item.toc = "20"  
# too long entries in the table of contents wrap around
# after this number of characters

doc.section = """
\chapter{$sectionTitle}\label{$sectionID}
\begin{description}
$content
\end{description}
"""

doc.section.toc = ""
# $sectionID $sectionTitleID $sectionTitle $content

doc.item = """
\item[\texttt{$header}\label{$itemID}]\mbox{~}\\*
$desc
"""

doc.item.toc = ""
#  \item $name\ref{$itemID}

doc.toc = r"\tableofcontents \newpage"

doc.body_toc = """
$tableofcontents
$moduledesc
$content
"""

doc.body_no_toc = """
$moduledesc
$content
"""

doc.file = """
% This file was generated by Nimrod.
% Generated: $date $time UTC
\documentclass[a4paper]{article}
\usepackage[left=2cm,right=3cm,top=3cm,bottom=3cm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{lmodern}
\usepackage{fancyvrb, courier}
\usepackage{tabularx}
\usepackage{hyperref}

\begin{document}
\title{$title $version}
\author{$author}

\tolerance 1414 
\hbadness 1414 
\emergencystretch 1.5em 
\hfuzz 0.3pt 
\widowpenalty=10000 
\vfuzz \hfuzz 
\raggedbottom 

\maketitle

\newenvironment{rstpre}{\VerbatimEnvironment\begingroup\begin{Verbatim}[fontsize=\footnotesize , commandchars=\\\{\}]}{\end{Verbatim}\endgroup}

% to pack tabularx into a new environment, special syntax is needed :-(
\newenvironment{rsttab}[1]{\tabularx{\linewidth}{#1}}{\endtabularx}

\newcommand{\rstsub}[1]{\raisebox{-0.5ex}{\scriptsize{#1}}}
\newcommand{\rstsup}[1]{\raisebox{0.5ex}{\scriptsize{#1}}}

\newcommand{\rsthA}[1]{\section{#1}}
\newcommand{\rsthB}[1]{\subsection{#1}}
\newcommand{\rsthC}[1]{\subsubsection{#1}}
\newcommand{\rsthD}[1]{\paragraph{#1}}
\newcommand{\rsthE}[1]{\paragraph{#1}}

\newcommand{\rstovA}[1]{\section*{#1}}
\newcommand{\rstovB}[1]{\subsection*{#1}}
\newcommand{\rstovC}[1]{\subsubsection*{#1}}
\newcommand{\rstovD}[1]{\paragraph*{#1}}
\newcommand{\rstovE}[1]{\paragraph*{#1}}

% Syntax highlighting:
\newcommand{\spanDecNumber}[1]{#1}
\newcommand{\spanBinNumber}[1]{#1}
\newcommand{\spanHexNumber}[1]{#1}
\newcommand{\spanOctNumber}[1]{#1}
\newcommand{\spanFloatNumber}[1]{#1}
\newcommand{\spanIdentifier}[1]{#1}
\newcommand{\spanKeyword}[1]{\textbf{#1}}
\newcommand{\spanStringLit}[1]{#1}
\newcommand{\spanLongStringLit}[1]{#1}
\newcommand{\spanCharLit}[1]{#1}
\newcommand{\spanEscapeSequence}[1]{#1}
\newcommand{\spanOperator}[1]{#1}
\newcommand{\spanPunctuation}[1]{#1}
\newcommand{\spanComment}[1]{\emph{#1}}
\newcommand{\spanLongComment}[1]{\emph{#1}}
\newcommand{\spanRegularExpression}[1]{#1}
\newcommand{\spanTagStart}[1]{#1}
\newcommand{\spanTagEnd}[1]{#1}
\newcommand{\spanKey}[1]{#1}
\newcommand{\spanValue}[1]{#1}
\newcommand{\spanRawData}[1]{#1}
\newcommand{\spanAssembler}[1]{#1}
\newcommand{\spanPreprocessor}[1]{#1}
\newcommand{\spanDirective}[1]{#1}
\newcommand{\spanCommand}[1]{#1}
\newcommand{\spanRule}[1]{#1}
\newcommand{\spanHyperlink}[1]{#1}
\newcommand{\spanLabel}[1]{#1}
\newcommand{\spanReference}[1]{#1}
\newcommand{\spanOther}[1]{#1}
\newcommand{\spantok}[1]{\frame{#1}}

$content
\end{document}
"""
light .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#
#
#           The Nimrod Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Simple alias analysis for the HLO and the code generators.

import
  ast, astalgo, types, trees, intsets, msgs
  
type
  TAnalysisResult* = enum
    arNo, arMaybe, arYes

proc isPartOfAux(a, b: PType, marker: var TIntSet): TAnalysisResult

proc isPartOfAux(n: PNode, b: PType, marker: var TIntSet): TAnalysisResult =
  result = arNo
  case n.kind
  of nkRecList: 
    for i in countup(0, sonsLen(n) - 1): 
      result = isPartOfAux(n.sons[i], b, marker)
      if result == arYes: return
  of nkRecCase:
    assert(n.sons[0].kind == nkSym)
    result = isPartOfAux(n.sons[0], b, marker)
    if result == arYes: return
    for i in countup(1, sonsLen(n) - 1): 
      case n.sons[i].kind
      of nkOfBranch, nkElse: 
        result = isPartOfAux(lastSon(n.sons[i]), b, marker)
        if result == arYes: return
      else: internalError("isPartOfAux(record case branch)")
  of nkSym:
    result = isPartOfAux(n.sym.typ, b, marker)
  else: internalError(n.info, "isPartOfAux()")
  
proc isPartOfAux(a, b: PType, marker: var TIntSet): TAnalysisResult = 
  result = arNo
  if a == nil or b == nil: return 
  if containsOrIncl(marker, a.id): return 
  if compareTypes(a, b, dcEqIgnoreDistinct): return arYes
  case a.kind
  of tyObject: 
    result = isPartOfAux(a.sons[0], b, marker)
    if result == arNo: result = isPartOfAux(a.n, b, marker)
  of tyGenericInst, tyDistinct:
    result = isPartOfAux(lastSon(a), b, marker)
  of tyArray, tyArrayConstr, tySet, tyTuple: 
    for i in countup(0, sonsLen(a) - 1): 
      result = isPartOfAux(a.sons[i], b, marker)
      if result == arYes: return 
  else: discard

proc isPartOf(a, b: PType): TAnalysisResult = 
  ## checks iff 'a' can be part of 'b'. Iterates over VALUE types!
  var marker = initIntSet()
  # watch out: parameters reversed because I'm too lazy to change the code...
  result = isPartOfAux(b, a, marker)

proc isPartOf*(a, b: PNode): TAnalysisResult =
  ## checks if location `a` can be part of location `b`. We treat seqs and
  ## strings as pointers because the code gen often just passes them as such.
  ##
  ## Note: `a` can only be part of `b`, if `a`'s type can be part of `b`'s
  ## type. Since however type analysis is more expensive, we perform it only
  ## if necessary.
  ##
  ## cases: 
  ##
  ## YES-cases:
  ##  x    <| x   # for general trees
  ##  x[]  <| x
  ##  x[i] <| x
  ##  x.f  <| x
  ##  
  ## NO-cases:
  ## x           !<| y    # depending on type and symbol kind
  ## x[constA]   !<| x[constB]
  ## x.f         !<| x.g
  ## x.f         !<| y.f  iff x !<= y
  ##
  ## MAYBE-cases:
  ##
  ##  x[] ?<| y[]   iff compatible type
  ##
  ## 
  ##  x[]  ?<| y  depending on type
  ##  
  if a.kind == b.kind:
    case a.kind
    of nkSym:
      const varKinds = {skVar, skTemp, skProc}
      # same symbol: aliasing:
      if a.sym.id == b.sym.id: result = arYes
      elif a.sym.kind in varKinds or b.sym.kind in varKinds: 
        # actually, a param could alias a var but we know that cannot happen
        # here. XXX make this more generic
        result = arNo
      else:
        # use expensive type check:
        if isPartOf(a.sym.typ, b.sym.typ) != arNo:
          result = arMaybe
    of nkBracketExpr:
      result = isPartOf(a[0], b[0])
      if len(a) >= 2 and len(b) >= 2:
        # array accesses:
        if result == arYes and isDeepConstExpr(a[1]) and isDeepConstExpr(b[1]):
          # we know it's the same array and we have 2 constant indexes; 
          # if they are 
          var x = if a[1].kind == nkHiddenStdConv: a[1][1] else: a[1]
          var y = if b[1].kind == nkHiddenStdConv: b[1][1] else: b[1]
          
          if sameValue(x, y): result = arYes
          else: result = arNo
        # else: maybe and no are accurate
      else:
        # pointer derefs:
        if result != arYes:
          if isPartOf(a.typ, b.typ) != arNo: result = arMaybe
      
    of nkDotExpr:
      result = isPartOf(a[0], b[0])
      if result != arNo:
        # if the fields are different, it's not the same location
        if a[1].sym.id != b[1].sym.id:
          result = arNo

    of nkHiddenDeref, nkDerefExpr:
      result = isPartOf(a[0], b[0])
      # weaken because of indirection:
      if result != arYes:
        if isPartOf(a.typ, b.typ) != arNo: result = arMaybe
      
    of nkHiddenStdConv, nkHiddenSubConv, nkConv:
      result = isPartOf(a[1], b[1])
    of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
      result = isPartOf(a[0], b[0])
    else: discard
    # Calls return a new location, so a default of ``arNo`` is fine.
  else:
    # go down recursively; this is quite demanding:
    const 
      Ix0Kinds = {nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
                  nkCheckedFieldExpr}
      Ix1Kinds = {nkHiddenStdConv, nkHiddenSubConv, nkConv}
      DerefKinds = {nkHiddenDeref, nkDerefExpr}
    case b.kind
    of Ix0Kinds:
      # a* !<| b.f  iff  a* !<| b
      result = isPartOf(a, b[0])
    
    of DerefKinds:
      # a* !<| b[] iff 
      if isPartOf(a.typ, b.typ) != arNo:
        result = isPartOf(a, b[0])
        if result == arNo: result = arMaybe
    
    of Ix1Kinds:
      # a* !<| T(b)  iff a* !<| b
      result = isPartOf(a, b[1])
    
    of nkSym:
      # b is an atom, so we have to check a:
      case a.kind
      of Ix0Kinds:
        # a.f !<| b*  iff  a.f !<| b*
        result = isPartOf(a[0], b)
      of Ix1Kinds:
        result = isPartOf(a[1], b)
      
      of DerefKinds:
        if isPartOf(a.typ, b.typ) != arNo:
          result = isPartOf(a[0], b)
          if result == arNo: result = arMaybe
      else: discard
    else: discard