#
#
#            Nimrod's Runtime Library
#        (c) Copyright 2008 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#


## This module contains the interface to the compiler's abstract syntax tree.
## Abstract syntax trees should be modified in macros.

#[[[cog
#def toEnum(name, elems):
#  body = ""
#  counter = 0
#  for e in elems:
#    if counter % 4 == 0: p = "\n    "
#    else: p = ""
#    body = body + p + 'n' + e + ', '
#    counter = counter + 1
#
#  return ("  TNimrod%s* = enum%s\n  TNim%ss* = set[TNimrod%s]\n" %
#            (name, body[:-2], name, name))
#
#enums = eval(open("data/ast.yml").read())
#cog.out("type\n")
#for key, val in enums.items():
#  if key[-4:] == "Flag": continue
#  cog.out(toEnum(key, val))
#]]]
type
  TNimrodNodeKind* = enum
    nnkNone, nnkEmpty, nnkIdent, nnkSym, 
    nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit, 
    nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit, 
    nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit, 
    nnkTripleStrLit, nnkMetaNode, nnkNilLit, nnkDotCall, 
    nnkCommand, nnkCall, nnkGenericCall, nnkExplicitTypeListCall, 
    nnkExprEqExpr, nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, 
    nnkInfix, nnkPrefix, nnkPostfix, nnkPar, 
    nnkCurly, nnkBracket, nnkBracketExpr, nnkPragmaExpr, 
    nnkRange, nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, 
    nnkIfExpr, nnkElifExpr, nnkElseExpr, nnkLambda, 
    nnkAccQuoted, nnkHeaderQuoted, nnkTableConstr, nnkQualified, 
    nnkHiddenStdConv, nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, 
    nnkCast, nnkAddr, nnkHiddenAddr, nnkHiddenDeref, 
    nnkObjDownConv, nnkObjUpConv, nnkChckRangeF, nnkChckRange64, 
    nnkChckRange, nnkStringToCString, nnkCStringToString, nnkPassAsOpenArray, 
    nnkAsgn, nnkFastAsgn, nnkDefaultTypeParam, nnkGenericParams, 
    nnkFormalParams, nnkOfInherit, nnkModule, nnkProcDef, 
    nnkConverterDef, nnkMacroDef, nnkTemplateDef, nnkIteratorDef, 
    nnkOfBranch, nnkElifBranch, nnkExceptBranch, nnkElse, 
    nnkMacroStmt, nnkAsmStmt, nnkPragma, nnkIfStmt, 
    nnkWhenStmt, nnkForStmt, nnkWhileStmt, nnkCaseStmt, 
    nnkVarSection, nnkConstSection, nnkConstDef, nnkTypeSection, 
    nnkTypeDef, nnkYieldStmt, nnkTryStmt, nnkFinally, 
    nnkRaiseStmt, nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, 
    nnkBlockStmt, nnkDiscardStmt, nnkStmtList, nnkImportStmt, 
    nnkFromStmt, nnkImportAs, nnkIncludeStmt, nnkAccessStmt, 
    nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkStmtListType, 
    nnkBlockType, nnkVm, nnkTypeOfExpr, nnkObjectTy, 
    nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen, 
    nnkRefTy, nnkPtrTy, nnkVarTy, nnkProcTy, 
    nnkEnumTy, nnkEnumFieldDef, nnkReturnToken
  TNimNodeKinds* = set[TNimrodNodeKind]
  TNimrodTypeKind* = enum
    ntyNone, ntyBool, ntyChar, ntyEmpty, 
    ntyArrayConstr, ntyNil, ntyGeneric, ntyGenericInst, 
    ntyGenericParam, ntyEnum, ntyAnyEnum, ntyArray, 
    ntyObject, ntyTuple, ntySet, ntyRange, 
    ntyPtr, ntyRef, ntyVar, ntySequence, 
    ntyProc, ntyPointer, ntyOpenArray, ntyString, 
    ntyCString, ntyForward, ntyInt, ntyInt8, 
    ntyInt16, ntyInt32, ntyInt64, ntyFloat, 
    ntyFloat32, ntyFloat64, ntyFloat128
  TNimTypeKinds* = set[TNimrodTypeKind]
  TNimrodSymKind* = enum
    nskUnknownSym, nskConditional, nskDynLib, nskParam, 
    nskTypeParam, nskTemp, nskType, nskConst, 
    nskVar, nskProc, nskIterator, nskConverter, 
    nskMacro, nskTemplate, nskField, nskEnumField, 
    nskForVar, nskModule, nskLabel, nskStub
  TNimSymKinds* = set[TNimrodSymKind]
#[[[end]]]

type
  TNimrodNode {.final.} = object   # hidden
  TNimrodSymbol {.final.} = object # hidden
  TNimrodType {.final.} = object   # hidden
  PNimrodType* {.compilerproc.} = ref TNimrodType
  PNimrodSymbol* {.compilerproc.} = ref TNimrodSymbol
  PNimrodNode* {.compilerproc.} = ref TNimrodNode
  expr* = PNimrodNode
  stmt* = PNimrodNode

# Nodes should be reference counted to make the `copy` operation very fast!
# However, this i<style>pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Numbe