How do you compile multiple files in different folders in D? - d

project
---|source
------ |controllers
-------|models
-------|lib
----------|field.d
-------|app.d
I run dub but I get this error:
Error: module field from file ... conflicts with another module field from
file source/lib/field.d
field.d looks like this:
module field;
class Field(T){
this(T def_val,bool required,string help_text);
bool validate();
private bool _validate();
}

Always put a module statement in any file that is going to be imported, and use a package name consistently as well to avoid conflicts.
So, instead of calling it simply module field;, call it module myapplication.field;, or even module myapplication.lib.field;, and of course, also import it by the same full name when you use it.
I'm not sure if dub will just work like that though (I don't use it personally), but the language lets you give a module any name, even if it doesn't match the filename, which helps in situations like this, avoiding name conflicts.
In general, if you give them all full, unique names, then compile them all at once: dmd app.d lib/field.d [and any other files your project has], things will just work.

Related

Get ScriptOrigin from v8::Module

It seems trivial, but I've searched far and wide.
I'm using this resource to make v8 run with ES Modules and I'm trying to implement my own search/load algorithm. Thus far, I've managed to make a simple system which loads a file from a known location, however I'd like to implement external modules. This means that the known location is actually unknown throughout the application. Take the following directory tree as an example:
~/
- index.js
import 'module1_index'; // This is successfully resolved to /libs/module1/module1_index.js
/libs/module1/
- module1_index.js
export * from './lib.js' // This import fails because it is looking for ./lib.js in ~/source
- lib.js
export /* literally anything */
The above example begins by executing the index.js file from ~. When module1_index.js is executed, lib.js is looked for from ~ and consequently fails. In order to address this, the files must be looked for relative to the file being executed at the moment, however I have not found a means to do this.
First Attempt
I'm given the opportunity to look for the file in the callResolve method (main.cpp:280):
v8::MaybeLocal<v8::Module> callResolve(v8::Local<v8::Context> context, v8::Local<v8::String> specifier, v8::Local<v8::Module> referrer)
or in loadModule (main.cpp:197)
v8::MaybeLocal<v8::Module> loadModule(char code[], char name[], v8::Local<v8::Context> cx)
however, as mentioned, I have found no function by which to extract the ScriptOrigin from the module. I should mention, when files are successfully resolved, the ScriptOrigin is initiated with the exact path to the file, and is reliable.
Second Attempt
I set up a stack, which keeps track of the current file being executed. Every import which is made is pushed onto the stack. Once the file has finished executing, it is popped. This also did not work, as there was no way to reliably determine once the file had finished executing.
It seems that the loadModule function does just that: loads. It does not execute, so I cannot pop after the module has loaded, as the imports are not fully resolved. The checkModule/execModule functions are only invoked on dynamic imports, making them useless to determining the completion of a static import.
I'm at a loss. I'm not familiar with v8 enough to know where to look, although I have dug through some NodeJS source code looking for an implementation, to no avail.
Any pointers are greatly appreciated.
Thanks.
Jake.
I don't know much about module resolution, but looking at V8's sources, I can see an example mapping a v8::Module to a std::string absolute_path, which sounds like what you're looking for. I'm not copying the whole code here, because the way it uses custom metadata is a bit involved; the short story is that it keeps a std::unordered_map to keep data about each module's source on the side. (I wonder if it would be possible to use Module::ScriptId() as that map's key, for simplification.)
Code search finds a bunch more example uses of InstantiateModule, mostly in tests. Tests often serve as useful examples/documentation :-)

Dynamically loading module and dynamically calling function in that module; Python 2.7

I am trying to write Python 2.7 code that will
Dynamically load a list / array of modules from a config file at startup
Call functions from those modules. Those functions are also designated in a config file (maybe the same config file, maybe a different one).
The idea is my code will have no idea until startup which modules to load. And the portion that calls the functions will have no idea which functions to call and which modules those functions belong to until runtime.
I'm not succeeding. A simple example of my situation is this:
The following is abc.py, a module that should be dynamically loaded (in my actual application I would have several such modules designated in a list / array in a config file):
def abc_fcn():
print("Hello World!")
def another_fcn():
print("BlahBlah")
The following is the .py code which should load abc.py (my actual code would need to import the entire list / array of modules from the config file). Both this .py file and abc.py are in the same folder / directory. Please note comments next to each statement.
module_to_import = "abc" #<- Will normally come from config file
fcn_to_call = "abc.abc_fcn" #<- Will normally come from config file
__import__(module_to_import) #<- No error
print(help(module_to_import)) #<- Works as expected
eval(fcn_to_call)() #<- NameError: name 'abc' is not defined
When I change the second line to the following...
fcn_to_call = "abc_fcn"
...the NameError changes to "name 'abc_fcn' is not defined".
What am I doing wrong? Thanks in advance for the help!
__import__ only returns the module specified, it does not add it to the global namespace. So to accomplish what you want, save the result as a variable, and then dynamically retrieve the function that you want. That could look like
fcn_to_call = 'abc_fcn'
mod = __import__(module_to_import)
func = getattr(mod, fcn_to_call)
func()
On a side note, abc is the name of name of the Abstract Base Classes builtin Python module, although I know you were probably just using this an example.
You should assign the returning value of __import__ to a variable abc so that you can actually use it as a module.
abc = __import__(module_to_import)

Why I am getting errors from TableGen-generated *.inc files (LLVM)?

I am trying to write an LLVM backend, when I am trying to build it, I get the following error message:
AbcGenRegisterInfo.inc: In static member function 'static const llvm::AbcFrameLowering* llvm::AbcGenRegisterInfo::getFrameLowering(const llvm::MachineFunction&)':
AbcGenRegisterInfo.inc:322:43: error: invalid static_cast from type 'const llvm::TargetFrameLowering*' to type 'const llvm::AbcFrameLowering*'
MF.getSubtarget().getFrameLowering());
^
Here is my AbcRegisterInfo.td (I copied it from here):
class AbcReg<string n> : Register<n> {
let namespace = "Abc";
}
def DUMMY_REG : AbcReg<"R0">;
def RegI64 : RegisterClass<"Abc", [i64], 64, (add DUMMY_REG)>;
I also overrided AbcSubtarget::getFrameLowering() method:
class AbcSubTarget : public AbcGenSubtargetInfo {
AbcFrameLowering *frameLowering;
// more fields and methods
const AbcFrameLowering *getFrameLowering() const override {
return frameLowering;
}
};
but the error message did not change.
I don't understand what to do - I can't just edit AbcGenRegisterInfo.inc, because it will be re-generated every time I will build LLVM, and I don't understand what's wrong in my TableGen files.
I also tried to remove AbcGenRegisterInfo.inc file from my build directory before compiling, but it had no effect.
Does AbcFrameLowering inherit from TargetFrameLowering? It looks like the static cast is complaining because the types are unrelated.
Also make sure the header with the definition of AbcFrameLowering is included before the .inc file is included otherwise the static cast will fail as well.
I have the same exact error, and while I cannot answer your question in full, I believe I can address one part of the issue. You said
I also tried to remove AbcGenRegisterInfo.inc file from my build directory before compiling, but it had no effect.
Unless you mean that AbcGenRegisterInfo.inc was regenerated (and therefore deleting it had no effect), the fact that its absence has no effect should be due to the fact that TableGen has the .inc.tmp file to rely on as a backup. I noticed that when I make with VERBOSE=1, there is a statement that suggests tablegen uses the .tmp files in this way.
Again, not a specific answer to your main question, but just to hopefully help address that issue when trying to debug.

Unit Testing in Nim: Is it possible to get the name of a source file at compile time?

I'm planning a project with multiple modules, and I was looking for a nice solution to run all existing unit tests in the project at once. I came up with the following idea: I can run nim --define:testing main.nim and use the following template as a wrapper for all my unit tests.
# located in some general utils module:
template runUnitTests*(code: stmt): stmt =
when defined(testing):
echo "Running units test in ..."
code
This seems to be working well so far.
As a minor tweak, I was wondering if I can actually print out the file name which is calling the runUnitTests template. Is there any reflection mechanism to get the source file name at compile time?
instantiationInfo seems to be what you want: http://nim-lang.org/docs/system.html#instantiationInfo,
template filename: string = instantiationInfo().filename
echo filename()
The template currentSourcePath from the system module returns the path of the current source by using a special compiler built-in, called instantiationInfo.
In your case, you need to print the locations of callers of your template, which means you'll have to use instantiationInfo directly with its default stack index argument of -1 (meaning one position up in the stack, or the caller):
# located in some general utils module:
template runUnitTests*(code: stmt): stmt =
when defined(testing):
echo "Running units test in ", instantiationInfo(-1).filename
code
It's worth mentioning that the Nim compiler itself uses a similar technique with this module, which get automatically imported in all other modules by applying a switch in nim.cfg:

Resolving module name conflicts, need to get at ORD_MAP signature

I'm working on a relatively large SML codebase. It was originally written to compile with MLton, but I'm now working with it under SML/NJ. I need to use RedBlackMapFn, which is defined in smlnj-lib.cm. However, I get an error:
elaborate/elaborate-bomenv.fun:9.20-9.27 Error: unbound signature: ORD_KEY
elaborate/elaborate-bomenv.fun:14.21-14.40 Error: unbound functor: RedBlackMapFn
elaborate/elaborate-bomenv.fun:32.20-32.27 Error: unbound signature: ORD_KEY
elaborate/elaborate-bomenv.fun:37.21-37.40 Error: unbound functor: RedBlackMapFn
So I assume that smlnj-lib.cm is not being pulled by CM. In an effort to fix this, I added $/smlnj-lib.cm to the sources.cm file in the directory that I'm working in. This causes a separate issue:
elaborate/sources.cm:25.1-25.18 Error: structure Random imported from $SMLNJ-LIB/Util/smlnj-lib.cm#243997(random.sml) and also from ./(sources.cm):lib/(sources.cm):basic/(sources.cm):random.sml
elaborate/sources.cm:25.1-25.18 Error: structure Queue imported from $SMLNJ-LIB/Util/smlnj-lib.cm#436143(queue.sml) and also from ./(sources.cm):lib/(sources.cm):basic/(sources.cm):two-list-queue.sml
No dice. I tried removing the Random structure that's coming from ./(sources.cm):lib/(sources.cm):basic/(sources.cm):random.sml, but it appears that it isn't equivalent to the one defined in the standard library, so I can't just substitute one for the other.
I'd like to use something like Python's import ... from ... as ...
mechanism to give a new name to the Random that's coming from the standard library, but CM's documentation doesn't offer any hints as to how I'd go about that.
How can I resolve a module naming conflict across multiple SML files?
I ended up splitting off the problematic file in to a separate .cm. The problem file here is elaborate-bomenv.{sig, fun}. The .cm file for this directory is sources.cm, which caused errors when it looked like:
Group
...
is
$/basis.cm
...
elaborate-bomenv.fun
elaborate-bomenv.sig
...
So instead, I made an elaborate-bomenv-sources.cm that looks like:
Group
signature ELABORATE_BOMENV
functor BOMEnv
is
$/smlnj-lib.cm
...
elaborate-bomenv.sig
elaborate-bomenv.fun
and changed the original sources.cm to read:
Group
...
is
$/basis.cm
...
./elaborate-bomenv-sources.cm
...
Which is ugly, but it works.