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
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 - The VM's instruction count limit was raised to 1 billion instructions in order
to support more complex computations at compile-time. 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, arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc,
floor, ceil, fmod 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.} = template mathop(op) {.dirty.} =
registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`) registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`)
@ -27,6 +29,9 @@ template ospathsop(op) {.dirty.} =
template systemop(op) {.dirty.} = template systemop(op) {.dirty.} =
registerCallback(c, "stdlib.system." & astToStr(op), `op Wrapper`) 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.} = template wrap1f_math(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getFloat(a, 0))) setResult(a, op(getFloat(a, 0)))
@ -37,30 +42,30 @@ template wrap2f_math(op) {.dirty.} =
setResult(a, op(getFloat(a, 0), getFloat(a, 1))) setResult(a, op(getFloat(a, 0), getFloat(a, 1)))
mathop op 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.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0))) setResult(a, op(getString(a, 0)))
osop op modop op
template wrap1s_ospaths(op) {.dirty.} = template wrap2s(op, modop) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0)))
ospathsop op
template wrap2s_ospaths(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0), getString(a, 1))) 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.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0))) op(getString(a, 0))
systemop op modop op
template wrap2svoid_system(op) {.dirty.} = template wrap2svoid(op, modop) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
op(getString(a, 0), getString(a, 1)) op(getString(a, 0), getString(a, 1))
systemop op modop op
proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} = proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
setResult(a, if a.currentException.isNil: "" setResult(a, if a.currentException.isNil: ""
@ -77,6 +82,9 @@ proc gorgeExWrapper(a: VmArgs) {.nimcall.} =
a.currentLineInfo) a.currentLineInfo)
setResult a, newTree(nkPar, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e)) setResult a, newTree(nkPar, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e))
proc getProjectPathWrapper(a: VmArgs) {.nimcall.} =
setResult a, gProjectPath
proc registerAdditionalOps*(c: PCtx) = proc registerAdditionalOps*(c: PCtx) =
wrap1f_math(sqrt) wrap1f_math(sqrt)
wrap1f_math(ln) wrap1f_math(ln)
@ -101,13 +109,15 @@ proc registerAdditionalOps*(c: PCtx) =
wrap1f_math(ceil) wrap1f_math(ceil)
wrap2f_math(fmod) wrap2f_math(fmod)
wrap2s_ospaths(getEnv) wrap2s(getEnv, ospathsop)
wrap1s_ospaths(existsEnv) wrap1s(existsEnv, ospathsop)
wrap1s_os(dirExists) wrap2svoid(putEnv, ospathsop)
wrap1s_os(fileExists) wrap1s(dirExists, osop)
wrap2svoid_system(writeFile) wrap1s(fileExists, osop)
wrap1s_system(readFile) wrap2svoid(writeFile, systemop)
wrap1s(readFile, systemop)
systemop getCurrentExceptionMsg systemop getCurrentExceptionMsg
registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} = registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1))) setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
systemop gorgeEx systemop gorgeEx
macrosop getProjectPath

View file

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

View file

@ -1,5 +1,8 @@
# bug #4462 # bug #4462
import macros import macros
import os
import ospaths
import strutils
block: block:
proc foo(t: typedesc) {.compileTime.} = proc foo(t: typedesc) {.compileTime.} =
@ -64,3 +67,18 @@ block:
const fact1000 = abc() const fact1000 = abc()
assert fact1000 == @[1, 2] 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