Skip to content

Commit

Permalink
Generate extern variable declarations
Browse files Browse the repository at this point in the history
Due to scala-native/scala-native#202 it is not possible to use `var` so
for now `val`s are used although not semantically correct.

References #70
  • Loading branch information
jonas committed Jun 28, 2018
1 parent a344255 commit 62292ad
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 1 deletion.
4 changes: 4 additions & 0 deletions bindgen/ir/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
s << *typeDef;
}

for (const auto &variable : ir.variables) {
s << *variable;
}

for (const auto &varDefine : ir.varDefines) {
s << *varDefine;
}
Expand Down
1 change: 0 additions & 1 deletion bindgen/ir/VarDefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include "Define.h"
#include "Variable.h"
#include <llvm/Support/raw_ostream.h>

/**
* Stores a pointer to Variable instance from IR
Expand Down
7 changes: 7 additions & 0 deletions bindgen/ir/Variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,10 @@

Variable::Variable(const std::string &name, Type *type)
: TypeAndName(name, type) {}

llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
const Variable &variable) {
s << " val " << variable.getName() << ": "
<< variable.getType()->str() << " = native.extern\n";
return s;
}
4 changes: 4 additions & 0 deletions bindgen/ir/Variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
#define SCALA_NATIVE_BINDGEN_VARIABLE_H

#include "TypeAndName.h"
#include <llvm/Support/raw_ostream.h>

class Variable : public TypeAndName {
public:
Variable(const std::string &name, Type *type);

friend llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
const Variable &variable);
};

#endif // SCALA_NATIVE_BINDGEN_VARIABLE_H
9 changes: 9 additions & 0 deletions tests/samples/Extern.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "Extern.h"

int forty_two = 42;
const char version[] = "0.1.0";

enum mode mode = USER;

struct version semver_instance = { .major = 1, .minor = 2, .patch = 3 };
struct version *semver = &semver_instance;
12 changes: 12 additions & 0 deletions tests/samples/Extern.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extern int forty_two;
extern const char version[];

enum mode { SYSTEM, USER };
extern enum mode mode;

struct version {
int major;
int minor;
int patch;
};
extern struct version *semver;
36 changes: 36 additions & 0 deletions tests/samples/Extern.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.scalanative.bindgen.samples

import scala.scalanative._
import scala.scalanative.native._

@native.link("bindgentests")
@native.extern
object Extern {
type enum_mode = native.CUnsignedInt
type struct_version = native.CStruct3[native.CInt, native.CInt, native.CInt]
val forty_two: native.CInt = native.extern
val version: native.CString = native.extern
val mode: enum_mode = native.extern
val semver: native.Ptr[struct_version] = native.extern
}

import Extern._

object ExternEnums {
final val enum_mode_SYSTEM: enum_mode = 0.toUInt
final val enum_mode_USER: enum_mode = 1.toUInt
}

object ExternHelpers {

implicit class struct_version_ops(val p: native.Ptr[struct_version]) extends AnyVal {
def major: native.CInt = !p._1
def major_=(value: native.CInt):Unit = !p._1 = value
def minor: native.CInt = !p._2
def minor_=(value: native.CInt):Unit = !p._2 = value
def patch: native.CInt = !p._3
def patch_=(value: native.CInt):Unit = !p._3 = value
}

def struct_version()(implicit z: native.Zone): native.Ptr[struct_version] = native.alloc[struct_version]
}
5 changes: 5 additions & 0 deletions tests/samples/VarDefine.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import scala.scalanative.native._
@native.link("bindgentests")
@native.extern
object VarDefine {
val a: native.CInt = native.extern
val constInt: native.CInt = native.extern
val constIntPointer: native.Ptr[native.CInt] = native.extern
val c: native.CInt = native.extern
val f: native.CFloat = native.extern
@name("a")
val A: native.CInt = native.extern
@name("constInt")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.scalanative.bindgen.samples

import utest._
import scalanative.native._

object ExternTests extends TestSuite {
val tests = Tests {
'forty_two - {
assert(Extern.forty_two == 42)
}

'mode - {
assert(Extern.mode == ExternEnums.enum_mode_USER)
}

'semver - {
import ExternHelpers._
assert(Extern.semver.major == 1 && Extern.semver.minor == 2 && Extern.semver.patch == 3)
}
}
}

0 comments on commit 62292ad

Please sign in to comment.