summary refs log tree commit diff stats
path: root/compiler/vmdeps.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/vmdeps.nim')
-rw-r--r--compiler/vmdeps.nim108
1 files changed, 108 insertions, 0 deletions
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
new file mode 100644
index 000000000..2a9929de0
--- /dev/null
+++ b/compiler/vmdeps.nim
@@ -0,0 +1,108 @@
+#
+#
+#           The Nimrod Compiler
+#        (c) Copyright 2013 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+import ast, 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 opTypeTrait*(n: PNode, context: PSym): PNode =
+    ## XXX: This should be pretty much guaranteed to be true
+    # by the type traits procs' signatures, but until the
+    # code is more mature it doesn't hurt to be extra safe
+    internalAssert n.len >= 2 and n.sons[1].kind == nkSym
+
+    let typ = n.sons[1].sym.typ.skipTypes({tyTypeDesc})
+    case n.sons[0].sym.name.s.normalize
+    of "name":
+      result = newStrNode(nkStrLit, typ.typeToString(preferExported))
+      result.typ = newType(tyString, context)
+      result.info = n.info
+    else:
+      internalAssert false
+
+  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
+