summary refs log tree commit diff stats
path: root/.gitignore
blob: 1971a23cb0a89192d05050a5d5db02d768650b11 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
*
!**/
!*.*
nimcache/

*.o
!/icons/*.o
*.exe
*.so
*.dylib
*.zip
*.iss

mapping.txt
tags
install.sh
deinstall.sh

doc/*.html
doc/*.pdf
doc/*.idx
/web/upload
build/*
bin/*

# iOS specific wildcards.
*.mode1v3
*.pbxuser
*.perspective
*.perspectivev3
*.swp
.DS_Store
project.xcworkspace/
xcuserdata/

# Generated files.
/compile.json
/compiler/nimrod.dot
/reject.json
/run.json
/testresults.html
/testresults.json
testament.db
/csources
ighlight .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 Nim Compiler
#        (c) Copyright 2015 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Implements type sanity checking for ASTs resulting from macros. Lots of
## room for improvement here.

import ast, astalgo, msgs, types

proc ithField(n: PNode, field: var int): PSym =
  result = nil
  case n.kind
  of nkRecList:
    for i in countup(0, sonsLen(n) - 1):
      result = ithField(n.sons[i], field)
      if result != nil: return
  of nkRecCase:
    if n.sons[0].kind != nkSym: internalError(n.info, "ithField")
    result = ithField(n.sons[0], field)
    if result != nil: return
    for i in countup(1, sonsLen(n) - 1):
      case n.sons[i].kind
      of nkOfBranch, nkElse:
        result = ithField(lastSon(n.sons[i]), field)
        if result != nil: return
      else: internalError(n.info, "ithField(record case branch)")
  of nkSym:
    if field == 0: result = n.sym
    else: dec(field)
  else: discard

proc annotateType*(n: PNode, t: PType) =
  let x = t.skipTypes(abstractInst+{tyRange})
  # Note: x can be unequal to t and we need to be careful to use 't'
  # to not to skip tyGenericInst
  case n.kind
  of nkObjConstr:
    let x = t.skipTypes(abstractPtrs)
    n.typ = t
    for i in 1 .. <n.len:
      var j = i-1
      let field = x.n.ithField(j)
      if field.isNil:
        globalError n.info, "invalid field at index " & $i
      else:
        internalAssert(n.sons[i].kind == nkExprColonExpr)
        annotateType(n.sons[i].sons[1], field.typ)
  of nkPar:
    if x.kind == tyTuple:
      n.typ = t
      for i in 0 .. <n.len:
        if i >= x.len: globalError n.info, "invalid field at index " & $i
        else: annotateType(n.sons[i], x.sons[i])
    elif x.kind == tyProc and x.callConv == ccClosure:
      n.typ = t
    else:
      globalError(n.info, "() must have a tuple type")
  of nkBracket:
    if x.kind in {tyArray, tySequence, tyOpenArray}:
      n.typ = t
      for m in n: annotateType(m, x.elemType)
    else:
      globalError(n.info, "[] must have some form of array type")
  of nkCurly:
    if x.kind in {tySet}:
      n.typ = t
      for m in n: annotateType(m, x.elemType)
    else:
      globalError(n.info, "{} must have the set type")
  of nkFloatLit..nkFloat128Lit:
    if x.kind in {tyFloat..tyFloat128}:
      n.typ = t
    else:
      globalError(n.info, "float literal must have some float type")
  of nkCharLit..nkUInt64Lit:
    if x.kind in {tyInt..tyUInt64, tyBool, tyChar, tyEnum}:
      n.typ = t
    else:
      globalError(n.info, "integer literal must have some int type")
  of nkStrLit..nkTripleStrLit:
    if x.kind in {tyString, tyCString}:
      n.typ = t
    else:
      globalError(n.info, "string literal must be of some string type")
  of nkNilLit:
    if x.kind in NilableTypes:
      n.typ = t
    else:
      globalError(n.info, "nil literal must be of some pointer type")
  else: discard