class Controller
def index
puts "hello"
end
end
macro handler(controller, action)
c = {{controller}}.new
c.{{action.id}}
end
# this doesn't work
temp = :index
handler Controller, temp
# this works
handler Controller, :index
Somehow on the first case, the macro gets expanded to c.temp instead of c.index
Is it possible to call a function inside a class like in above code snippet.
Edit:
I am trying to achieve something like this, https://github.com/Amber-Crystal/amber/blob/master/src/amber/dsl/router.cr#L16
temp is a runtime variable, while macros are interpreted at compile time. That means the Crystal compiler can't actually know the value of temp, as it is only known at runtime. Tracing variables to literal values could be done to some degree, but would be expensive and brittle to use, since a small change may make it impossible.
When you call a macro, the arguments are actual AST nodes, expressions of parsed source code. So in your example the macro gets a TypeNode as first argument and a Var as second argument.
Related
I'm working through compiler warnings in a project, attempting to clean up the code, and one warning/error that has confused me is an unused-label warning for the following code.
STATE(initialize)
It says that the "initialize" label is defined but not used. STATE is a #define macro that is as follows:
#define STATE(x) x: __TRACE__("enter", #x);
And the __TRACE__ macro is as follows:
#define __TRACE__(y,x) dbg.printf(DebugIO::debug2,"FSM:" y "(" x ")\n");
Note, I did not write this code, and am just working through a project attempting to correct as many warnings as possible. But from what I can tell, the initialize label is passed to __TRACE__ where it's used as an argument for a printf() call.
So, why is it not used? Does the compiler not look at preprocessor directives for variable usage?
How would I correct this?
from what I can tell, the initialize label is passed to __TRACE__ where it's used as an argument for a printf() call.
No, it is not, actually. The x parameter of STATE() is not the same as the x parameter of __TRACE__().
In the statement STATE(initialize), the x parameter is initialize, so x: becomes simply initialize: (the label in question), but #x stringifies the input value of x as "initialize" in this case, so STATE(initialize) expands to this:
initialize: __TRACE__("enter", "initialize");
And then, in the __TRACE__ macro, the y parameter is "enter" and the x parameter is "initialize", so __TRACE__("enter", "initialize") expands to this:
dbg.printf(DebugIO::debug2,"FSM:" "enter" "(" "initialize" ")\n");
And lastly, string literals that are separated by only whitespace are merged together by the compiler, so the final code for STATE(initialize) looks like this:
initialize: dbg.printf(DebugIO::debug2,"FSM:enter(initialize)\n");;
And since there is no goto or other statement that references the initialize label, that is why you get a warning about it.
How would I correct this?
Unless there is an actual goto initialize statement in the code somewhere, I would just get rid of the label altogether:
#define STATE(x) __TRACE__("enter", #x);
The very reason for the warning is the fact that
x: TRACE...
introduces the label to be used with goto. It bears to reason that there is no goto to initialize state (it looks like we are looking at FSM implementation).
There is probably no way to remove this warning without re-working the framework (for example, adding a special state macro which does not define a label for states you never get into), but one can also just silence this particular warning for the project.
Note that __attribute__((unused)) can be used on a label.
Converting the macro argument to a string doesn't count as "using" the label that happens to have the same name (remember that labels are a separate namespace from variables anyway, let alone macro arguments).
Using the (GCC extension) unary && operator to take the address of the label might also suppress the warning, but as a rule you should avoid anything that looks like a dynamic goto unless you really know what you're doing. So prefer the attribute version.
Note also that __TRACE__ is a reserved name since it contains 2 underscores next to each other.
I'd like to be able to write some Lua code like this:
y=x+1
and be able to get the names of all variables (x and y in this case) so that I can read from/write to them in the calling C++ program. The problem is that x is uninitialized, so this chunk will not execute and therefore neither variable will appear in the globals table. My current work-around is to have the user explicitly declare that they want to initialize x externally (as well as how to initialize it), then I pre-pend the Lua script with an appropriate declaration for x, so that the final script looks like this:
x= /*some value calculated outside of the Lua script*/
y=x+1
Although this works, I'd really like to have a way to automatically list all uninitialized variables in the Lua code and present them to the user, instead of the user having to remember to explicitly declare them. A function that parses the Lua code without executing it would probably be what I want. I've tried the function luaL_loadstring, but x and y don't show up in the globals table.
Since this is a bit vague, I'll give an actual use case. My C++ code basically performs optimizations on functions, such as finding a root or a maximum. I want the user to be able to define custom functions (in the form of Lua scripts), which in general will have one or more inputs and one or more outputs. The user will define which parameters the optimizer should operate on. For example, the user may want to find the minimum of y=x^2. The way I'd like it to work is that the user writes a Lua script consisting of nothing more than y=x^2, and then tells the optimizer to vary x in order to minimize y. On each iteration of the optimizer, the current guess for x would be automatically pasted into the user script, which is then executed, and then the value of y is pulled from the Lua state to be fed back to the optimizer. This is how I have it working now, however it's a bit clumsy from a UX perspective because the user has to manually declare that x is a Lua variable. This gets tedious when there are many variables that require manual declaration. It would be much better if I could automatically scan the script and show the user a list of their undeclared variables so they could then use drag-and-drop and other GUI sugar to do the manual declaration.
Lua isn't meant to work like that. Lua/C interop is intended to be collaborative; it's not supposed to be that C can do whatever it wants.
Using your example, if you have a Lua script that is supposed to take a value from C and return that value + 1, then you spell that in Lua like this:
local x = ... --Get the first parameter to the chunk.
return x + 1 --Adds 1 to the value and returns it.
You compile this string into a Lua chunk and call it like a Lua function. You pass it the value you want to manipulate and get the return value from the Lua stack.
The idea is not that C code can just reach into a Lua script and shove data into it arbitrarily. The above chunk takes parameters from the user and provides return values to the user. That's typically how C interfaces with Lua.
Yes, you can write values to globals and have the Lua script read them, and write its "results" to globals that the external code reads. But this is not the most effective way to interact with scripts.
I'd really like to have a way to automatically list all uninitialized variables
There's no such thing in Lua as an "uninitialized variable". Not in the way that you mean.
Yes, there are globals. But whether that global has a value or not is not something the Lua script can control. A global is global after all; you can set a global variable from outside of the script (for example, see lua_setglobal). If you do, then a script that reads from it will read the value you set. But it doesn't know anything about that.
What you want is a static code analyzer/Lua linter. Take a look at Luacheck:
Luacheck is a static analyzer and a linter for Lua. Luacheck detects
various issues such as usage of undefined global variables, unused
variables, and values, accessing uninitialized variables, unreachable
code and more. Most aspects of checking are configurable: there are
options for defining custom project-related globals, for selecting set
of standard globals (version of Lua standard library), for filtering
warnings by type and name of related variables, etc. The options can
be used on the command line, put into a config or directly into
checked files as Lua comments.
There is also Lualint, and similar Lua linters for Atom, VSCode, or your fav IDE.
In learning the LLVM framework, I am trying to implement an 'optimization' pass that prints the name of each method at runtime when the method is called.
I read that global variables should only be created in a Module Pass, and I create the strings there (one per function), with
Constant* data = ConstantDataArray::getString(M.getContext(), F.getName());
GlobalVariable* gvar =
new GlobalVariable(M,
data->getType(),
true,
GlobalValue::ExternalLinkage,
data,
"fname_" + F.getName().str());
This works fine, insofar as the strings are laid out correctly in memory in the assembly file generated by the 'optimized' bitcode.
However, I have not found a way to insert calls to print these strings in the Function Pass.
I want to use
Value* string = F.getValueSymbolTable().lookup("fname_" + F.getName().str());
CallInst* call = builder.CreateCall(emitPutS(string, builder, &TLI));
but string comes back as NULL. Is there a better way to look up global variables from a function?
Figured it out:
Basic blocks have a getModule() method, and modules have a getGlobalVariable(StringRef Name) method.
Alternatively, IRBuilder:CreateGlobalStringPtr(...) can be called from the function pass, and the Value* returned can be passed to emitPutS(...) directly. The module pass was not necessary.
Note, CallInst* call = builder.CreateCall(emitPutS(string, builder, &TLI)); is incorrect. emitPutS(...) will create the call in the basic block already. The CreateCall is erroneous.
In C++ I want to make functions that when declared, gets automatically added to a map( or vector, doesn't really matter in this case) as a function pointer and is called later automatically. For example this would be useful if I am writing unit test framework and I just want users to declare each of their unit tests like this:
UNIT_TEST_FUNCTION(function_name){
// do something
}
and instead something like this gets called
void function_name(){
//do something
}
int temp = register_function("function_name", function_name);
Where register_function() adds the user defined function in a map of function pointers for example. So basically, I need a mechanism that adds additional lines of code after a function definition, so that some action is performed automatically on the defined function. Is this possible using macros perhaps?
A macro can only generate a consecutive block of text. It can't lay things out the way you show in the question.
However if you're willing to rearrange a little, it can be done.
#define UNIT_TEST_FUNCTION(function_name) \
void function_name(); // forward declaration \
int temp##function_name = register_function(#function_name, function_name); \
void function_name()
A single preprocessor macro can't do what you want because it can only generate a single, contiguous block of text. Preprocessor macros are stupid in the sense that they don't understand anything about the language -- hence the preprocessor in 'preprocessor macro'.
What you can do is use a pair of macros or tuple of macros to delimit the begin and end of your test case mapping, and a single macro for each individual test case. Something along these lines:
TEST_CASES_BEGIN
UNIT_TEST_FUNCTION(function_name){
// do something
}
TEST_CASES_END
The Boost unit test facility uses a mechanism very similar to this. You might even (eventually) find this design to be a little more expressive than the design you are trying to achieve.
I have the following code in Lua:
ABC:
test (X)
The test function is implemented in C + +. My problem is this: I need to know what the variable name passed as parameter (in this case X). In C + + only have access to the value of this variable, but I must know her name.
Help please
Functions are not passed variables; they are passed values. Variables are just locations that store values.
When you say X somewhere in your Lua code, that means to get the value from the variable X (note: it's actually more complicated than that, but I won't get into that here).
So when you say test(X), you're saying, "Get the value from the variable X and pass that value as the first parameter to the function test."
What it seems like you want to do is change the contents of X, right? You want to have the test function modify X in some way. Well, you can't really do that directly in Lua. Nor should you.
See, in Lua, you can return values from functions. And you can return multiple values. Even from C++ code, you can return multiple values. So whatever it is you wanted to store in X can just be returned:
X = test(X)
This way, the caller of the function decides what to do with the value, not the function itself. If the caller wants to modify the variable, that's fine. If the caller wants to stick it somewhere else, that's also fine. Your function should not care one way or the other.
Also, this allows the user to do things like test(5). Here, there is no variable; you just pass a value directly. That's one reason why functions cannot modify the "variable" that is passed; because it doesn't have to be a variable. Only values are passed, so the user could simply pass a literal value rather than one stored in a variable.
In short: you can't do it, and you shouldn't want to.
The correct answer is that Lua doesn't really support this, but there is the debug interface. See this question for the solution you're looking for. If you can't get a call to debug to work directly from C++, then wrap your function call with a Lua function that first extracts the debug results and then calls your C++ function.
If what you're after is a string representation of the argument, then you're kind of stuck in lua.
I'm thinking something like in C:
assert( x==y );
Which generates a nice message on failure. In C this is done through macros.
Something like this (untested and probably broken).
#define assert(X) if(!(X)) { printf("ASSERION FAILED: %s\n", #X ); abort(); }
Here #X means the string form of the arguments. In the example above that is "x==y". Note that this is subtly different from a variable name - its just the string used in the parser when expanding the macro.
Unfortunately there's no such corresponding functionality in lua. For my lua testing libraries I end up passing the stringified version as part of the expression, so in lua my code looks something like this:
assert( x==y, "x==y")
There may be ways to make this work as assert("x==y") using some kind of string evaluation and closure mechanism, but it seemed to tricky to be worth doing to me.
EDIT:
While this doesn't appear to be possible in pure lua, there's a patched version that does seem to support macros: http://lua-users.org/wiki/LuaMacros . They even have an example of a nicer assert.