summary refs log blame commit diff stats
path: root/compiler/vmdeps.nim
blob: 2a40276d1d494ea793d68d49a9904ee6e373cef2 (plain) (tree)
1
2
3
4
5
6
7
8
9








                                                   
                                                 























































                                                                             


























                                                                      
#
#
#           The Nimrod Compiler
#        (c) Copyright 2013 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

import ast, types, msgs, osproc, streams, options

proc readOutput(p: PProcess): string =
  result = ""
  var output = p.outputStream
  discard p.waitForExit
  while not output.atEnd:
    result.add(output.readLine)

proc opGorge*(cmd, input: string): string =
  var p = startCmd(cmd)
  if input.len != 0:
    p.inputStream.write(input)
    p.inputStream.close()
  result = p.readOutput

proc opSlurp*(file: string, info: TLineInfo, module: PSym): string = 
  try:
    let filename = file.FindFile
    result = readFile(filename)
    # we produce a fake include statement for every slurped filename, so that
    # the module dependencies are accurate:
    appendToModule(module, newNode(nkIncludeStmt, info, @[
      newStrNode(nkStrLit, filename)]))
  except EIO:
    result = ""
    LocalError(info, errCannotOpenFile, file)

when false:
  proc opExpandToAst*(c: PEvalContext, original: PNode): PNode =
    var
      n = original.copyTree
      macroCall = n.sons[1]
      expandedSym = macroCall.sons[0].sym

    for i in countup(1, macroCall.sonsLen - 1):
      macroCall.sons[i] = evalAux(c, macroCall.sons[i], {})

    case expandedSym.kind
    of skTemplate:
      let genSymOwner = if c.tos != nil and c.tos.prc != nil:
                          c.tos.prc 
                        else:
                          c.module
      result = evalTemplate(macroCall, expandedSym, genSymOwner)
    of skMacro:
      # At this point macroCall.sons[0] is nkSym node.
      # To be completely compatible with normal macro invocation,
      # we want to replace it with nkIdent node featuring
      # the original unmangled macro name.
      macroCall.sons[0] = newIdentNode(expandedSym.name, expandedSym.info)
      result = evalMacroCall(c, macroCall, original, expandedSym)
    else:
      InternalError(macroCall.info,
        "ExpandToAst: expanded symbol is no macro or template")
      result = emptyNode

  proc opIs*(n: PNode): PNode =
    InternalAssert n.sonsLen == 3 and
      n[1].kind == nkSym and n[1].sym.kind == skType and
      n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
    
    let t1 = n[1].sym.typ

    if n[2].kind in {nkStrLit..nkTripleStrLit}:
      case n[2].strVal.normalize
      of "closure":
        let t = skipTypes(t1, abstractRange)
        result = newIntNode(nkIntLit, ord(t.kind == tyProc and
                                          t.callConv == ccClosure and 
                                          tfIterator notin t.flags))
      of "iterator":
        let t = skipTypes(t1, abstractRange)
        result = newIntNode(nkIntLit, ord(t.kind == tyProc and
                                          t.callConv == ccClosure and 
                                          tfIterator in t.flags))
    else:
      let t2 = n[2].typ
      var match = if t2.kind == tyTypeClass: matchTypeClass(t2, t1)
                  else: sameType(t1, t2)
      result = newIntNode(nkIntLit, ord(match))

    result.typ = n.typ