add syntax cIncludeDir "$projpath/include"; do not use recursive search paths; add test tests/tnimterop_cpp.nim

This commit is contained in:
Timothee Cour 2018-11-27 18:06:17 -05:00
commit d00aeeafdd
6 changed files with 99 additions and 15 deletions

View file

@ -17,7 +17,8 @@ proc execCmd(cmd:string)=
exec cmd
task test, "Test":
execCmd "nim c -r tests/tnimterop"
execCmd "nim c -r tests/tnimterop_c.nim"
execCmd "nim c -r tests/tnimterop_cpp.nim"
task installWithDeps, "install dependencies":
for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter",

View file

@ -2,20 +2,29 @@ import macros, os, strformat, strutils
import ast, getters, globals, lisp
proc interpPath(dir: string): string=
# TODO: more robust: needs a DirSep after "$projpath"
result = dir.replace("$projpath", getProjectPath())
proc joinPathIfRel(path1: string, path2: string): string =
if path2.isAbsolute:
result = path2
else:
result = joinPath(path1, path2)
proc findPath(path: string, fail = true): string =
# As is
result = path.replace("\\", "/")
if not fileExists(result) and not dirExists(result):
# Relative to project path
result = joinPath(getProjectPath(), path).replace("\\", "/")
result = joinPathIfRel(getProjectPath(), path).replace("\\", "/")
if not fileExists(result) and not dirExists(result):
if fail:
echo "File or directory not found: " & path
quit(1)
doAssert false, "File or directory not found: " & path
else:
return ""
proc cSearchPath*(path: string): string =
proc cSearchPath*(path: string): string {.compileTime.}=
result = findPath(path, fail = false)
if result.len == 0:
var found = false
@ -24,9 +33,7 @@ proc cSearchPath*(path: string): string =
if fileExists(result) or dirExists(result):
found = true
break
if not found:
echo "File or directory not found: " & path
quit(1)
doAssert found, "File or directory not found: " & path & " gSearchDirs: " & $gSearchDirs
macro cDebug*(): untyped =
gDebug = true
@ -50,13 +57,12 @@ macro cDefine*(name: static string, val: static string = ""): untyped =
echo result.repr
macro cAddSearchDir*(dir: static string): untyped =
result = newNimNode(nnkStmtList)
let fullpath = cSearchPath(dir)
if fullpath notin gSearchDirs:
gSearchDirs.add(fullpath)
var dir = interpPath(dir)
if dir notin gSearchDirs:
gSearchDirs.add(dir)
macro cIncludeDir*(dir: static string): untyped =
var dir = interpPath(dir)
result = newNimNode(nnkStmtList)
let

8
tests/include/test2.cpp Normal file
View file

@ -0,0 +1,8 @@
#include "test2.hpp"
// BUG: should complain
// # include test2.h
int test_call_int() {
return 5;
}

20
tests/include/test2.hpp Normal file
View file

@ -0,0 +1,20 @@
#define TEST_INT 512
int test_call_int();
struct Foo{
int bar;
};
class Foo1{
int bar1;
};
template<typename T>
struct Foo2{
int bar2;
};
typedef Foo2<int> Foo2_int;

View file

@ -3,8 +3,8 @@ import nimterop/cimport
cDebug()
cDefine("FORCE")
cIncludeDir "include"
cAddSearchDir "include"
cIncludeDir "$projpath/include"
cAddSearchDir "$projpath/include"
cCompile cSearchPath("test.c")
cImport cSearchPath "test.h"

49
tests/tnimterop_cpp.nim Normal file
View file

@ -0,0 +1,49 @@
import nimterop/cimport
import unittest
cDebug()
cIncludeDir "$projpath/include"
cAddSearchDir "$projpath/include"
cCompile cSearchPath "test2.cpp"
# TODO: allow this to have correct language: cImport("test2.h")
cImport cSearchPath "test2.hpp"
check TEST_INT == 512
check test_call_int() == 5
var foo: Foo
check foo.bar == 2
# var foo2: Foo2[int]
# var foo2: Foo2Int
when false:
doAssert TEST_FLOAT == 5.12
doAssert TEST_HEX == 0x512
var
pt: PRIMTYPE
ct: CUSTTYPE
s: STRUCT1
s2: STRUCT2
s3: STRUCT3
e: ENUM
e2: ENUM2 = enum5
pt = 3
ct = 4
s.field1 = 5
s2.field1 = 6
s3.field1 = 7
e = enum1
e2 = enum4
doAssert test_call_int_param(5).field1 == 5
doAssert test_call_int_param2(5, s2).field1 == 11
doAssert test_call_int_param3(5, s).field1 == 10
doAssert test_call_int_param4(e) == e2