Is it possible to define a VHDL function with no parameters?
I'm trying to compute the number of bits in a record type, but to do so it is necessary to create an instance of that type. Therefore, since I can't just define const BITS = t_rec.a'length + t_rec.b'length, I would like to define a function function BITS() return natural that instantiates a record rec : t_rec and returns rec.a'length + rec.b'length. However, the compiler fails with unexpected '(') at the function declaration, before it even reaches the definition.
I would just include an unused, dummy parameter, but I suspect that the lint tools would complain.
Defining subtypes for each record field in advance of the record would be too verbose.
Complete example:
package pack is function BITS() return natural; end package pack; package body pack is function BITS() return natural is begin return 0; end function; end package body pack;
Error message:
pack.vhd:1:30: empty interface list not allowed
You should leave out the parentheses when defining a function with no inputs, eg:
function BITS return natural is
variable rec : rec_t;
begin
return rec.a'length + rec.b'length;
end function;
You should not include the parentheses when you call the function, either. eg:
report integer'image( BITS );
not
report integer'image( BITS() );
https://www.edaplayground.com/x/5fMB
Related
I'm working on a MATLAB app that programatically creates anonymous functions to evaluate any native MATLAB function and pass it a list of variables as argument. In the example below, 'formula' contains a string with the function and arguments to be evaluated (e.g., "sum( var1, var2 )" ). The formulas sometimes contain function calls nested within function calls, so the code below would be used recursively until obtaining the final result:
Func2 = str2func( sprintf( '#(%s) %s', strjoin( varNames, ',' ), formula ) );
This evaluates fine for native MATLAB functions. But there's a particular case of a function (named Func1) I made myself that not only needs the list of variables but also an object as argument, like this:
function output = Func1( anObject, varNames )
% do some stuff with the object and the vars
end
For this particular function, I've tried doing this:
Func2 = str2func( sprintf( '#(%s,%s) %s', "objectToPassToFunc1", strjoin( varNames, ',' ), "Func1(objectToPass,""" + strjoin( varNames, '","' ) +""")" ) )
...which doesn't throw an error, but Func1 doesn't receive the objectToPassToFunc1, instead it gets values from one of the variables in varNames. And I don't know why.
So how can I correctly pass the object to Func1????
Matlab doesn't care about the type of arguments you pass to a function. As a matter of fact, the input could be scalar, vector, matrix, and even an object of a class. See the following example.
classdef ClassA
methods
function print(~)
disp('method print() is called.');
end
end
end
This class has only one method. Now, let us define an anonymous function func which accepts one input.
func = #(arg) arg.print;
Notice that we explicitly assume that the input is an object of ClassA. If you pass another type of data to this function, Matlab will throw an error. To test the code,
obj = ClassA;
func = #(arg) arg.print;
func(obj)
To avoid the error, you may need to check the type of the input before using it. For example,
function [] = func(arg)
% check if arg is an object of ClassA
if isa(arg,'ClassA')
arg.print;
end
end
Now you can pass different types for the input without getting an error.
I am trying to create a Lua function "on the fly", from within another function. The new Lua function, to be called "fx", should operate on a scalar variable -- say, x -- and return f_x(x), where f_x(x) could be something such as "x+1" or "x^2". Importantly, the function name "fx" is given (as it will be used, with this name, from within other functions), but its properties -- specifically, whether it returns "x+1" or "x^2" -- should be modifiable dynamically.
Suppose that "x" is the scalar-valued input variable and that "y" is a string that contains an instruction, such as "x+1" or "x^2", that "fx" is supposed to impose on "x". I've naively tried
function make_func (x,y)
return ( function fx(x) return y end )
end
but that doesn't work.
Any help and guidance will be greatly appreciated!
It's not clear how "fx" is supposed to enter the picture, but if you have a string that contains potentially executable Lua code (a Lua expression which would compile if done so in a context where "x" exists), then this seems to be a simple case of building a string from bits of Lua code and executing it:
function make_func (x, lua_op)
return dostring("return function(x) return " .. lua_op .. " end")
end
This requires lua_op to store a string which is a legitimate Lua expression.
If you want to store the function in the global variable "fx", you can do that before returning it:
function make_func (x, lua_op)
fx = dostring("return function(x) return " .. lua_op .. " end")
return fx
end
I have been trying to learn some lua recently, and I came across something I didn't understand with functions today, the code below didn't work
function iter()
local i=0
return function() print(i); i=i+1; end
end
iter()
iter()
I had to assign a variable to my function iter() and then call the variable before it would run:
function iter()
local i=0
return function() print(i); i=i+1; end
end
it=iter()
it()
it()
can anyone clarify why that is?
First of all, functions are just values. Your outer function is assigned to the variable iter. That function returns an anonymous function. ("Anonymous" just means you did not give the function a name before returning it.)
Secondly, an argument list in parentheses is basically an operator that calls a function (unless it's in a function declaration). When you use that operator, the function runs and the expression results in the return value.
In the statement iter(), you call a function and ignore its return value, so you never get to see the inner function run.
In the statement it = iter(), you end up with a named function called it. Every time you call it, it increments the i variable from inside the iter call that created it.
As a side note, it would be legal to say iter()() to immediately call the returned function. This wouldn't actually be useful in your case, because each call to iter returns a fresh closure with i starting at zero.
I am trying to add a function to my Conky which prints the length of a string for debug purposes. The code, inside a file called test.lua, is pretty trivial:
function test(word)
return string.len(word)
end
...and I load it like this. In my conky.config section I have:
lua_load = '/home/xvlaze/test.lua',
lua_draw_hook_pre = 'test'
...in the conky.text section I have:
${lua test "fooo"}
...where test is the name of the function and fooo the string to test.
The expected result should be a printed 4 in Conky, but instead of that I get:
conky: llua_do_call: function conky_test execution failed: /home/xvlaze/test.lua:2: attempt to index a nil value (local 'string')
conky: llua_getstring: function conky_test didn't return a string, result discarded
I have browsed through the documentation, but I can't find anything. Does anybody know where the failure is?
Several guidances on how to implement functions in Conky:
First of all: YOU MUST USE conky_ BEFORE YOUR FUNCTION'S NAME.
Otherwise, you will get the following error when running your Conky:
attempt to call a nil value
Secondly: YOU MUST ALWAYS RETURN A VALUE.
I don't mind repeating it - it is crucial. Otherwise, you will get:
function foobar didn't return a string, result discarded
function_result
...in your terminal, and your Conky will be left empty of values related to your extra code. Nothing will be printed regarding your function.
Last but not least: YOU MUST ALWAYS CALL YOUR FUNCTION LIKE:
lua_load = '/path/to/function.lua',
-- Whatever content...
${lua function_name function_parameter1 function_parameterN} -- In case you use more than one parameter.
In summary, a dummy function template could be:
MAIN FILE (conky.conf):
conky.config = {
-- Whatever content... Lua styled comments.
lua_load = '/path/to/function.lua',
}
conky.text = [[
# Whatever content... In this section comments are started with '#'!
${lua function_name parameter}
]]
FUNCTION FILE:
function conky_function_name(parameter)
-- Whatever content... Remember this is Lua, not conky.text syntax. Always use '--' comments!
return whatever -- No return, no party. A function MUST always return something!
end
I'm writing long digit arythmetics. This is a function for adding to longint long binary digits. I need to output the sum inside the function, to debug it. How could I do it, without creating new variables?
function add(var s1,s2:bindata;shift:longint):bindata;
var l,i:longint;
o:boolean;
begin
writeln(s1.len,' - ',s2.len);
o:=false;
l:=max(s1.len,s2.len);
add.len:=0;
for i:=1 to l do begin
if o then Begin
if s1.data[i+shift] then Begin
if (s2.data[i]) then add.data[i+shift]:=true
Else add.data[i+shift]:=false;
End
else if s2.data[i] then add.data[i+shift]:=false
else Begin
add.data[i+shift]:=true;
o:=false;
End;
End
Else Begin
if s1.data[i+shift] then Begin
if s2.data[i] then
Begin
add.data[i+shift]:=false;
o:=true;
End
Else add.data[i+shift]:=true;
End
else if s2.data[i] then add.data[i+shift]:=true
else add.data[i+shift]:=false;
End;
output(add); //Can I output a variable?
end;
add.len:=l;
if o then Begin
inc(add.len);
add.data[add.len]:=true;
End;
end;
You are accumulating the result of the function within the function result variable, which is generally fine, but uses an outdated style, and leads to exactly the problem you're facing here. You're trying to report an intermediate value of the function result, and to do that, you're trying to reference the name of the function, add. When you do that, though, the compiler interprets it as an attempt to report the function itself, rather than the expected return value of this particular invocation of the function. You'll get the address of the function, if output is defined to accept function addresses; otherwise, you'll get a compiler error.
If your compiler offers a certain common language extension, then you should use the implicit Result variable to refer to the intermediate return value instead of continuing to refer to it by the function name. Since Result is declared implicitly, you wouldn't have to create any other variables. The compiler automatically recognizes Result and uses it as an alias for the function's return value. Simply find every place you write add within the function and replace it with Result. For example:
if o then begin
Inc(Result.len);
Result.data[Result.len] := True;
end;
Turbo Pascal, Free Pascal, GNU Pascal, and Delphi all support the implicit Result variable, but if you've managed to get stuck with a compiler that doesn't offer that extension, then you have no choice but to declare another variable. You could name it Result, and then implement your function with one additional line at the end, like so:
function add(var s1, s2: bindata; shift: longint): bindata;
var
l, i: longint;
o: boolean;
Result: bindata;
begin
{
Previous function body goes here, but with
`add` replaced by `Result`
}
{ Finally, append this line to copy Result into the
function's return value immediately before returning. }
add := Result;
end;