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

 
                            
                                         




                                                   
                                                                     
 
                                     

                             

                               
                    

                                        
                       
 










                                                                
                                                                          









                                        
                                                                          





                                  
 
                                                                    
      
                                




                                                                             
                 
                                             
               


                                                                  
             








                                                                         


                                             
                     

                                              





























                                                                           





                                                                 

















                                                         
                                                          






























                                                                               


                                                 












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

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

proc readOutput(p: Process): string =
  result = ""
  var output = p.outputStream
  while not output.atEnd:
    result.add(output.readLine)
    result.add("\n")
  if result.len > 0:
    result.setLen(result.len - "\n".len)
  discard p.waitForExit

proc opGorge*(cmd, input, cache: string): string =
  if cache.len > 0:# and optForceFullMake notin gGlobalOptions:
    let h = secureHash(cmd & "\t" & input & "\t" & cache)
    let filename = options.toGeneratedFile("gorge_" & $h, "txt")
    var f: File
    if open(f, filename):
      result = f.readAll
      f.close
      return
    var readSuccessful = false
    try:
      var p = startProcess(cmd, options={poEvalCommand, poStderrToStdout})
      if input.len != 0:
        p.inputStream.write(input)
        p.inputStream.close()
      result = p.readOutput
      readSuccessful = true
      writeFile(filename, result)
    except IOError, OSError:
      if not readSuccessful: result = ""
  else:
    try:
      var p = startProcess(cmd, options={poEvalCommand, poStderrToStdout})
      if input.len != 0:
        p.inputStream.write(input)
        p.inputStream.close()
      result = p.readOutput
    except IOError, OSError:
      result = ""

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 IOError:
    localError(info, errCannotOpenFile, file)
    result = ""

proc atomicTypeX(name: string; t: PType; info: TLineInfo): PNode =
  let sym = newSym(skType, getIdent(name), t.owner, info)
  sym.typ = t
  result = newSymNode(sym)
  result.typ = t

proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode

proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode =
  result = newNodeIT(nkBracketExpr, info, t)
  result.add atomicTypeX(name, t, info)
  for i in 0 .. < t.len:
    if t.sons[i] == nil:
      let void = atomicTypeX("void", t, info)
      void.typ = newType(tyEmpty, t.owner)
      result.add void
    else:
      result.add mapTypeToAst(t.sons[i], info)

proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
  template atomicType(name): expr = atomicTypeX(name, t, info)

  case t.kind
  of tyNone: result = atomicType("none")
  of tyBool: result = atomicType("bool")
  of tyChar: result = atomicType("char")
  of tyNil: result = atomicType("nil")
  of tyExpr: result = atomicType("expr")
  of tyStmt: result = atomicType("stmt")
  of tyEmpty: result = atomicType"void"
  of tyArrayConstr, tyArray:
    result = newNodeIT(nkBracketExpr, info, t)
    result.add atomicType("array")
    result.add mapTypeToAst(t.sons[0], info)
    result.add mapTypeToAst(t.sons[1], info)
  of tyTypeDesc:
    if t.base != nil:
      result = newNodeIT(nkBracketExpr, info, t)
      result.add atomicType("typeDesc")
      result.add mapTypeToAst(t.base, info)
    else:
      result = atomicType"typeDesc"
  of tyGenericInvocation:
    result = newNodeIT(nkBracketExpr, info, t)
    for i in 0 .. < t.len:
      result.add mapTypeToAst(t.sons[i], info)
  of tyGenericInst, tyGenericBody, tyOrdinal, tyUserTypeClassInst:
    result = mapTypeToAst(t.lastSon, info)
  of tyDistinct:
    if allowRecursion:
      result = mapTypeToBracket("distinct", t, info)
    else:
      result = atomicType(t.sym.name.s)
  of tyGenericParam, tyForward: result = atomicType(t.sym.name.s)
  of tyObject:
    if allowRecursion:
      result = newNodeIT(nkObjectTy, info, t)
      if t.sons[0] == nil:
        result.add ast.emptyNode
      else:
        result.add mapTypeToAst(t.sons[0], info)
      result.add copyTree(t.n)
    else:
      result = atomicType(t.sym.name.s)
  of tyEnum:
    result = newNodeIT(nkEnumTy, info, t)
    result.add copyTree(t.n)
  of tyTuple: result = mapTypeToBracket("tuple", t, info)
  of tySet: result = mapTypeToBracket("set", t, info)
  of tyPtr: result = mapTypeToBracket("ptr", t, info)
  of tyRef: result = mapTypeToBracket("ref", t, info)
  of tyVar: result = mapTypeToBracket("var", t, info)
  of tySequence: result = mapTypeToBracket("seq", t, info)
  of tyProc: result = mapTypeToBracket("proc", t, info)
  of tyOpenArray: result = mapTypeToBracket("openArray", t, info)
  of tyRange:
    result = newNodeIT(nkBracketExpr, info, t)
    result.add atomicType("range")
    result.add t.n.sons[0].copyTree
    result.add t.n.sons[1].copyTree
  of tyPointer: result = atomicType"pointer"
  of tyString: result = atomicType"string"
  of tyCString: result = atomicType"cstring"
  of tyInt: result = atomicType"int"
  of tyInt8: result = atomicType"int8"
  of tyInt16: result = atomicType"int16"
  of tyInt32: result = atomicType"int32"
  of tyInt64: result = atomicType"int64"
  of tyFloat: result = atomicType"float"
  of tyFloat32: result = atomicType"float32"
  of tyFloat64: result = atomicType"float64"
  of tyFloat128: result = atomicType"float128"
  of tyUInt: result = atomicType"uint"
  of tyUInt8: result = atomicType"uint8"
  of tyUInt16: result = atomicType"uint16"
  of tyUInt32: result = atomicType"uint32"
  of tyUInt64: result = atomicType"uint64"
  of tyBigNum: result = atomicType"bignum"
  of tyConst: result = mapTypeToBracket("const", t, info)
  of tyMutable: result = mapTypeToBracket("mutable", t, info)
  of tyVarargs: result = mapTypeToBracket("varargs", t, info)
  of tyIter: result = mapTypeToBracket("iter", t, info)
  of tyProxy: result = atomicType"error"
  of tyBuiltInTypeClass: result = mapTypeToBracket("builtinTypeClass", t, info)
  of tyUserTypeClass:
    result = mapTypeToBracket("concept", t, info)
    result.add t.n.copyTree
  of tyCompositeTypeClass: result = mapTypeToBracket("compositeTypeClass", t, info)
  of tyAnd: result = mapTypeToBracket("and", t, info)
  of tyOr: result = mapTypeToBracket("or", t, info)
  of tyNot: result = mapTypeToBracket("not", t, info)
  of tyAnything: result = atomicType"anything"
  of tyStatic, tyFromExpr, tyFieldAccessor:
    result = newNodeIT(nkBracketExpr, info, t)
    result.add atomicType("static")
    if t.n != nil:
      result.add t.n.copyTree

proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode =
  result = mapTypeToAst(t, info, true)