functions,tables and for in Lua - arrays

Right now I'm doing some tests but I cant seem to find what is wrong with this code - any idea?
function IATetris(Pieza,Rotacion,Array)
io.write("The table the script received has: ",Pieza,"\n")
RotacionInicial = Rotacion
PosInicial = 7
final = #Array --this gets the size of the array
i = 1
for y = 1, 20 do --the array of my tetris board is 20 in x and 14 in y so it would be something like this Array2D[20][14]
io.write(" First for y ",y,"\n")
Array2D[y]={} --clearing the new array
for x = 1,14 do
io.write(" First for x ",x,"\n")
if i == final then break end
io.write(" First for i",i,"\n")
Array2D[y][x] = Array[i]
i= i+1 --seems like you cant use i++ in lua
end
end
end
What I'm doing is getting 2 integers and 1 Array. I'm having to write in the console to check where the program is actually going, and what I'm getting is...
The first log message: "The table the script received has: "
and the second log message: " First for y "
But I don't get any further than those so probably the program is crashing there? This function is being called like every 20 seconds or so. I have really no idea why this is happening. Any help would be really appreciated, thank you.

If this line logs:
io.write(" First for y ",y,"\n")
and this line does not log:
io.write(" First for x ",x,"\n")
Then the problem is on one of these lines:
Array2D[y]={} --clearing the new array
for x = 1,14 do
for x... definitely works for me, so I'd suggest it's the Array2D line. There is nothing syntactically wrong with it, so it must be a runtime error. Runtime errors should be reported by Lua or the application it is embedded into. If they aren't and the function just "stops" then you are debugging blind, and you will waste a lot of time on problems like this.
The only error I can think might happen on that line would be if Array2D is not a table. Since you are trying to index it, it needs to be. Array2D isn't declared in your function, this is fine if it is a global variable that is already defined elsewhere. However if it is meant to be a local variable just for this function then you should add local Array2D = {} to it.
Without knowing what Array2D is, or what your actual error is even, it's hard to give a more accurate answer. If you really have no better method of finding out the problem than logging, this, just before the Array2D line, should test my hypothesis:
io.write("Array2D is: ", type(Array2D), "\n")

Looks like Array2D is not initialized (or not a table), so it craps on Array2D[y]={}.
You can use pcall to call a function and trap errors, like this:
local ok, msg = pcall(IATetris, pieza, rotacion, array)
if not ok then
print("ERROR:", msg)
end
Side note: you should be using the local keyword whenever possible to limit the scope of your variables.

Related

Frama-C Plugin: Resolve array-values

I'm working on a frama-c plugin that should resolve the values of all kinds of varibles. I managed to dereference pointers and structs and typedefs and print the correspoinding values.
Now I'm struggling with getting the values of an array.
Here is my approach so far, description below:
| TArray (typ, exp, bitsSizeofTypCache, attributes) -> (
let len = Cil.lenOfArray exp in
let rec loc_rec act max =
if act < max then(
let packed = match exp with
| Some x -> x
in
let inc = Cil.increm packed act in
let new_offset = (Index(inc, offset)) in
rec_struct_solver typ (vi_name^"["^(string_of_int act)^"]") (lhost, new_offset);
loc_rec (act+1) max
);
in
loc_rec 0 len
)
I managed to get the length of the array by using Cil.lenOfArray with the expression-option when matching the type.
Now my approach is to go over the length of the array, increment the describing expression and modify the offset, and then handle the variable like a local variable (in the next recursion-step).
I think this idea basically makes sense, but I don't know if the increment is done correctly (value ok, or multiplied by some size or something), or other things don't work.
The program compiles (with the warning that the matching doesn't include all cases, which is irrelevant, since I can only work with expressions, not with NONE), but doesn't output the (correct) results.
Is this the nearly the right approach, or am I doing it completely wrong? Can someone give me some hints on how to get the array's values?
If something is unclear (since it is hard to describe what I want), please let me know, I will modify my question.
EDIT
The expected result of a Code like this
int arr[3];
arr[0]=0;
arr[1]=1;
arr[2]=2;
arr[0]=3;
Should be something like that:
arr[0]=0;3
arr[1]=1
arr[2]=2
I simply want to get all the values at every index of the array over the program.
While I get only empty results, like arr[1]={ } (also for the other Indizes), so I simply don't get results for this Kind of access I use.
Your original code queries the value for the index Index(inc, offset), where inc is Cil.increm packed act, act is the current index, and packed is the size of the array. So you are basically making queries for size+0, size+1 ... size-+(size-1). All these offsets are invalid, because they are out-of-bounds. This is why you obtain the value Cvalue.V.bottom which pretty-prints as .
The simplest fix to your original code would have been to replace packed by a call to Cil.zero Cil_datatype.Location.unknown, but your own fix is fine.
I figured out how to do it:
The trick was, that with Cil.integer, a new constant exp can be built!
With Cil.integer Cil_datatype.Location.unknown act, I created a new exp.
With this exp, I was able to build an Index-Offset. Then I added this new offset to the actual offset of the array. This new offset was used to build a new lval.
By doing this, I got the access to the arrays indizes.
Now my output looks ok:
arrayTest:arr[0]---> 0; 3
arrayTest:arr[1]---> 1
arrayTest:arr[2]---> 2

C - Segmentation Fault when Calling an certain indexes from an array of function pointer

So I've ran into this problem before and I was wondering if anyone could help me with it. It's really strange and I've never seen anything like it.
So I have this setup function which basically fills my global array of operation functions:
//A function Pointer is a type def that accepts two ints
fcnptr *opCode_Array; //Global Array of fcnptrs
void SetUp() {
int i;
fcnptr temp[41] = {NULL,movOP_1,mviOP_2,mifOP_3,mitOP_4,lriOP_5,ldrOP_6,strOP_7,mvrOP_8,addOP_9,addriOP_10,subOP_11,mulOP_12, divOP_13, orOP_14, andOP_15, notOP_16, bOP_17, beqOP_18, bneOP_19, bgtOP_20, bgeOP_21, bltOP_22, bleOP_23, pushdOP_24, pushrOP_25, pushiOP_26, popdOP_27, poprOP_28, putiOP_29, putsOP_30, lineOP_31, getiOP_32, getsOP_33, callOP_34, retOP_35, stopOP_36,addOP_9,addriOP_10,subOP_11,mulOP_12};
opCode_Array = (fcnptr*)malloc(41 * sizeof(fcnptr));
//fill global array with functions
for(i = 0; i < 41; i++) {
opCode_Array[i] = temp[i];
}
}
Later on I have a function that calls the operation functions like so:
void fetchExecute(int codeStoreLength) {
while(instructionPointer < codeStoreLength) {
//ip does not point to the instruction it is to execute during the loop, but the instruction that follows it.
instructionPointer += 3;
(*opCode_Array[codeStore[instructionPointer - 3]])(codeStore[instructionPointer - 2], codeStore[instructionPointer - 1]);
}
}
So normally this all works fine and dandy but last night and today I ran into some errors that caused segmentation faults when only calling specific functions, or more accurately, trying to access specific indexes of the opCode_Array.
If you noticed, I have two versions of the Addop, one at index 9 and another at index 37. When testing my function, I would get a segmentation fault when calling Addop at index 9 even when the code was completely commented out. I came up with a quick and dirty hack and just added another Addop to the end of the array and called addop from index 37 from now on. This worked completely fine and passed all the tests.
Now, another index is displaying the same behavior. It might be worth mentioning that this same index worked perfectly on previous tests. This has happened to a couple of my functions so I would rather just figure out why it's doing this than just move indexes around forever.
So far, I've tried p;laying around with pointers and making opCode_Array static but neither have helped..
Edit: Thank you everyone for the tips and help. I wasn't able to find the root of the problem but I was able to fix it by making the array local to fetchexecute instead of global. I would post more code but this is a school project that gets reused every year..
Lessons Learned? Don't make globals unless you have too I guess....

Weird array assignment in MATLAB: [x,t]=house_dataset

I'm learning work with neural networks through MATLAB samples. In one sample of the documentation (R2012a), there is a weird assignment
[x,t] = house_dataset
Basically, house_dataset is a 13×506 2D array. But the assignment results in two arrays:
x, a 13×506 2D array which is to be used as input to our neural network; t a 1×506 array which is to be used as target for network.
I don't know how this is done. Is it based on some fundamental thing I don't know about MATLAB matrices?
I even assigned house_dataset into another variable
h_dataset = house_dataset;
and then MATLAB gave an error when I tried to do this:
[x,t] = h_dataset;
Error message reads:
>> [x,t] = h_dataset;
Too many output arguments.
Does anyone know what this is all about?
It is normal behaviour for functions (and house_dataset is one of many functions in toolbox)
Function returns 2 values
function [inputs,targets] = house_dataset
but if you just enter
variable = house_dataset;
it returns and saves to variable only first value which is [inputs]
check the behaviour of very simple function
function [out1,out2] = test
out1 = 'first out';
out2 = 'second out';
end
and then call in matlab command window:
[first, second] = test
first = test
second = test
if you want to get only second value use something like:
[~,second] = test

indexed object dot notation method gives scalar property

I'm seeing an issue when I try and reference an object property after having used a dot notation to apply a method.
it only occurs when I try to index the initial object
classdef myclassexample
properties
data
end
methods
function obj = procData(obj)
if numel(obj)>1
for i = 1:numel(obj)
obj(i) = obj(i).procData;
end
return
end
%do some processing
obj.data = abs(obj.data);
end
end
end
then assigning the following
A = myclassexample;
A(1).data= - -1;
A(2).data = -2;
when calling the whole array and collecting the property data it works fine
[A.procData.data]
if i try and index A then i only get a scalar out
[A([1 2]).procData.data]
even though it seems to do fine without the property call
B = A([1 2]).procData;
[B.data]
any ideas?
I would definitely call this a bug in the parser; A bug because it did not throw an error to begin with, and instead allowed you to write: obj.method.prop in the first place!
The fact that MATLAB crashed in some variations of this syntax is a serious bug, and should definitely be reported to MathWorks.
Now the general rule in MATLAB is that you should not "index into a result" directly. Instead, you should first save the result into a variable, and then index into that variable.
This fact is clear if you use the form func(obj) rather than obj.func() to invoke member methods for objects (dot-notation vs. function notation):
>> A = MyClass;
>> A.procData.data % or A.procData().data
ans =
[]
>> procData(A).data
Undefined variable "procData" or class "procData".
Instead, as you noted, you should use:
>> B = procData(A): % or: B = A.pocData;
>> [B.data]
FWIW, this is also what happens when working with plain structures and regular functions (as opposed to OOP objects and member functions), as you cannot index into the result of a function call anyway. Example:
% a function that works on structure scalar/arrays
function s = procStruct(s)
if numel(s) > 1
for i=1:numel(s)
s(i) = procStruct(s(i));
end
else
s.data = abs(s.data);
end
end
Then all the following calls will throw errors (as they should):
% 1x2 struct array
>> s = struct('data',{1 -2});
>> procStruct(s).data
Undefined variable "procStruct" or class "procStruct".
>> procStruct(s([1 2])).data
Undefined variable "procStruct" or class "procStruct".
>> feval('procStruct',s).data
Undefined variable "feval" or class "feval".
>> f=#procStruct; f(s([1 2])).data
Improper index matrix reference.
You might be asking yourself why they decided to not allow such syntax. Well it turns out there is a good reason why MATLAB does not allow indexing into a function call (without having to introduce a temporary variable that is), be it dot-indexing or subscript-indexing.
Take the following function for example:
function x = f(n)
if nargin == 0, n=3; end
x = magic(n);
end
If we allowed indexing into a function call, then there would be an ambiguity in how to interpret the following call f(4):
should it be interpreted as: f()(4) (that is call function with no arguments, then index into the resulting matrix using linear indexing to get the 4th element)
or should it interpreted as: f(4) (call the function with one argument being n=4, and return the matrix magic(4))
This confusion is caused by several things in the MATLAB syntax:
it allows calling function with no arguments simply by their name, without requiring the parentheses. If there is a function f.m, you can call it as either f or f(). This makes parsing M-code harder, because it is not clear whether tokens are variables or functions.
parentheses are used for both matrix indexing as well as function calls. So if a token x represents a variable, we use the syntax x(1,2) as indexing into the matrix. At the same time if x is the name of a function, then x(1,2) is used to call the function with two arguments.
Another point of confusion is comma-separated lists and functions that return multiple outputs. Example:
>> [mx,idx] = max(magic(3))
mx =
8 9 7
idx =
1 3 2
>> [mx,idx] = max(magic(3))(4) % now what?
Should we return the 4th element of each output variables from MAX, or 4th element from only the first output argument along with the full second output? What about when the function returns outputs of different sizes?
All of this still applies to the other types of indexing: f()(3)/f(3), f().x/f.x, f(){3}/f{3}.
Because of this, MathWorks decided avoid all the above confusion and simply not allow directly indexing into results. Unfortunately they limited the syntax in the process. Octave for example has no such restriction (you can write magic(4)(1,2)), but then again the new OOP system is still in the process of being developed, so I don't know how Octave deals with such cases.
For those interested, this reminds me of another similar bug with regards to packages and classes and directly indexing to get a property. The results were different whether you called it from the command prompt, from a script, or from a M-file function...

Fortran array addition goes wrong

I'm trying to add two arrays, but for some reason the target array only contains zeros.
When i compile and run the program i don't get any errors, but the output file is wrong.
In the code i call dhscf which fills the arrays Gnaatm and Gnascf with values, i (try) to save those in gavenaa and gavenas, and the call dhscf again to get new values for Gnaatm an Gnascf. When i write all those arrays to files gavenas en gavenaa seem to be empty although Gnaatm and Gnascf aren't.
The code i'm using is:
module var
real(dp), dimension(:), allocatable :: Gnaatm(:), Gnascf(:), gavenaa(:), &
& gavenas(:)
end module
grdsam.f:
allocate (Gnaatm(nasize))
allocate (Gnascf(nasize))
allocate (gavenaa(nasize))
allocate (gavenas(nasize))
call dhscf(.....)
gavenaa = Gnaatm
gavenas = Gnascf
do ipt = 1, npt
call dhscf(....)
gavenaa = Gnaatm + gavenaa
gavenas = Gnascf + gavenas
enddo
open(unit=12, file="Zgavenaatm.txt", status="replace")
do iwrite = 1, nasize
write(12, *), iwrite, gavenaa(iwrite), Gnaatm(iwrite)
enddo
close(12)
open(unit=12, file="Zgavenascf.txt", status="replace")
do iwrite = 1, nasize
write(12, *), iwrite, gavenas(iwrite), Gnascf(iwrite)
enddo
close(12)
deallocate (Gnaatm)
deallocate (Gnascf)
deallocate (gavenaa)
deallocate (gavenas)
end grdsam
When i run the program i don't get errors, but the output file is wrong. Typical output is like this:
10 0.0000000000000000 -2.35488624992556957E-015
11 0.0000000000000000 -4.75822627213221874E-017
12 0.0000000000000000 -7.16040821425613171E-014
13 0.0000000000000000 8.33283089385797112E-021
14 0.0000000000000000 -1.04121906025281556E-014
The second column only contains zeros, but the third column does contain numbers.
So the arrays 'Gnaatm' and 'Gnascf' contain numbers, but somehow adding them to 'gavenaa' and 'gavenas' goes wrong. Can any one tell me what i'm doing wrong?
ps. i'm using the gfortran compiler on Ubuntu 12.
I would be really surprised if any fortran compiler had issues with something as basic as adding up two arrays, so either the code shown is not exactly the code you're using, or the problem is in parts of the code that are omitted.
First, you don't show it here, so I'll ask it: do you have implicit none in your code? Continuing without it would be a waste of time; it avoids many "silly" errors, like misspelled variable names.
Second, have you tried the old-fashioned debugging method of writing (parts of) the arrays you're interested in to the screen? Just put in some statements like
write(*,*) gavenaa(:5)
immediately after an assignment statement, to see if the arrays ever contain values you expect.
If you still can't find the place where things go wrong, try to reduce the code to a minimal, but complete, example that exhibits the same problem. Often the mistake will be found while doing this, but if not, it is much easier for others to help you if you can give them some code that is complete and compiles directly.
If you're just doing whole array assignments why are you bothering with forall constructs ? Since all the arrays in question have the same size you could simplify this block:
gavenaa(1:nasize) = Gnaatm(1:nasize)
forall(icount = 1:nasize)
gavenas(icount) = Gnascf(icount) + gavenas(icount)
end forall
to
gavenaa = Gnaatm
gavenas = Gnascf + gavenas
Likewise in the rest of your code.
I can't say that your use of the forall is incorrect, but it seems unnecessary and slimming your code down a bit will help you, and us, to properly diagnose and fix whatever problem you have.

Resources