Added a few useful os calls to VM (#7440)

This commit is contained in:
genotrance
2018-04-12 06:59:14 -05:00
committed by Andreas Rumpf
parent 84982e5e17
commit c3cc52087f
4 changed files with 57 additions and 24 deletions

View File

@@ -54,3 +54,4 @@
- The VM's instruction count limit was raised to 1 billion instructions in order
to support more complex computations at compile-time.
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to VM.

View File

@@ -13,7 +13,9 @@ from math import sqrt, ln, log10, log2, exp, round, arccos, arcsin,
arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc,
floor, ceil, fmod
from os import getEnv, existsEnv, dirExists, fileExists, walkDir
from os import getEnv, existsEnv, dirExists, fileExists, putEnv, walkDir
from options import gProjectPath
template mathop(op) {.dirty.} =
registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`)
@@ -27,6 +29,9 @@ template ospathsop(op) {.dirty.} =
template systemop(op) {.dirty.} =
registerCallback(c, "stdlib.system." & astToStr(op), `op Wrapper`)
template macrosop(op) {.dirty.} =
registerCallback(c, "stdlib.macros." & astToStr(op), `op Wrapper`)
template wrap1f_math(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getFloat(a, 0)))
@@ -37,30 +42,30 @@ template wrap2f_math(op) {.dirty.} =
setResult(a, op(getFloat(a, 0), getFloat(a, 1)))
mathop op
template wrap1s_os(op) {.dirty.} =
template wrap0(op, modop) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op())
modop op
template wrap1s(op, modop) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0)))
osop op
modop op
template wrap1s_ospaths(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0)))
ospathsop op
template wrap2s_ospaths(op) {.dirty.} =
template wrap2s(op, modop) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0), getString(a, 1)))
ospathsop op
modop op
template wrap1s_system(op) {.dirty.} =
template wrap1svoid(op, modop) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0)))
systemop op
op(getString(a, 0))
modop op
template wrap2svoid_system(op) {.dirty.} =
template wrap2svoid(op, modop) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
op(getString(a, 0), getString(a, 1))
systemop op
modop op
proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
setResult(a, if a.currentException.isNil: ""
@@ -77,6 +82,9 @@ proc gorgeExWrapper(a: VmArgs) {.nimcall.} =
a.currentLineInfo)
setResult a, newTree(nkPar, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e))
proc getProjectPathWrapper(a: VmArgs) {.nimcall.} =
setResult a, gProjectPath
proc registerAdditionalOps*(c: PCtx) =
wrap1f_math(sqrt)
wrap1f_math(ln)
@@ -101,13 +109,15 @@ proc registerAdditionalOps*(c: PCtx) =
wrap1f_math(ceil)
wrap2f_math(fmod)
wrap2s_ospaths(getEnv)
wrap1s_ospaths(existsEnv)
wrap1s_os(dirExists)
wrap1s_os(fileExists)
wrap2svoid_system(writeFile)
wrap1s_system(readFile)
wrap2s(getEnv, ospathsop)
wrap1s(existsEnv, ospathsop)
wrap2svoid(putEnv, ospathsop)
wrap1s(dirExists, osop)
wrap1s(fileExists, osop)
wrap2svoid(writeFile, systemop)
wrap1s(readFile, systemop)
systemop getCurrentExceptionMsg
registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
systemop gorgeEx
macrosop getProjectPath

View File

@@ -1293,3 +1293,7 @@ macro unpackVarargs*(callee: untyped; args: varargs[untyped]): untyped =
result = newCall(callee)
for i in 0 ..< args.len:
result.add args[i]
proc getProjectPath*(): string = discard
## Returns the path to the currently compiling project

View File

@@ -1,5 +1,8 @@
# bug #4462
import macros
import os
import ospaths
import strutils
block:
proc foo(t: typedesc) {.compileTime.} =
@@ -18,7 +21,7 @@ block:
# #6379
static:
import algorithm
var numArray = [1, 2, 3, 4, -1]
numArray.sort(cmp)
assert numArray == [-1, 1, 2, 3, 4]
@@ -57,10 +60,25 @@ block:
result = @[0]
result.setLen(2)
var tmp: int
for i in 0 .. <2:
for i in 0 ..< 2:
inc tmp
result[i] = tmp
const fact1000 = abc()
assert fact1000 == @[1, 2]
# Tests for VM ops
block:
static:
assert "vm" in getProjectPath()
let b = getEnv("UNSETENVVAR")
assert b == ""
assert existsEnv("UNSERENVVAR") == false
putEnv("UNSETENVVAR", "VALUE")
assert getEnv("UNSETENVVAR") == "VALUE"
assert existsEnv("UNSETENVVAR") == true
assert fileExists("MISSINGFILE") == false
assert dirExists("MISSINGDIR") == false