I'm pretty new to OpenSCAD, but have got most of it down. However, I'm not sure how I can do stack-like operations. It doesn't really matter what data structure is used, as long as I can push and pop numbers. Is this possible?
I worked extensively with stacks while implementing a string processing library.
The trick is to use nested right associative lists of size = 2, e.g. ["foo", ["bar", []]].
If you want to push something to a stack:
function push(stack, item) = [item, stack];
If you want to pop the stack:
function pop(stack) = stack[1];
And if you want to peek or retrieve the value that was popped:
function peek(stack) = stack[0];
You can also implement map/reduce functions using recursion:
function map(stack) =
push(
map(pop(stack)),
f(peek(stack))
);
function reduce(stack) =
f(peek(stack))?
push(
reduce(pop(stack)),
f(peek(stack))
)
:
reduce(pop(stack))
;
Of course, now that version 2015.03 is out you might consider using list comprehension, assuming that's what you really need.
Related
What would be the best way to capture the inner text in the following case?
inner_text = any*;
tag_cdata = '<![CDATA[' inner_text >cdata_start %cdata_end ']]>';
The problem is, it seems like the cdata_end action fires several times due to the fact that inner_text could match ].
I found the solution. You need to handle non-determinism. It wasn't clear initially, but the correct solution is something like this:
inner_text = any*;
tag_cdata = '<![CDATA[' inner_text >text_begin %text_end ']]>' %cdata_end;
action text_begin {
text_begin_at = p;
}
action text_end {
text_end_at = p;
}
action cdata_end {
delegate.cdata(data.byteslice(text_begin_at, text_end_at-text_begin_at))
}
Essentially, you wait until you are sure you parsed a complete CDATA tag before firing the callback, using information you previously captured.
In addition, I found that some forms of non-determinism in Ragel need to be explicitly handled using priorities. While this seems a bit ugly, it is the only solution in some cases.
When dealing with a pattern such as (a+ >a_begin %a_end | b)* you will find that the events are called for every single a encountered, rather than at the longest sub-sequence. This ambiguity, in some cases, can be solved using the longest match kleene star **. What this does is it prefers to match the existing pattern rather than wrapping around.
What was surprising to me, is that this actually modifies the way events are called, too. As an example, this produces a machine which is unable to buffer more than one character at a time when invoking callbacks:
%%{
machine example;
action a_begin {}
action a_end {}
main := ('a'+ >a_begin %a_end | 'b')*;
}%%
Produces:
You'll notice that it calls a_begin and a_end every time.
In contrast, we can make the inner loop and event handling greedy:
%%{
machine example;
action a_begin {}
action a_end {}
main := ('a'+ >a_begin %a_end | 'b')**;
}%%
which produces:
Following definitions print already the result of the functions in the table:
function plus1(zahl) print(zahl+1) end
function plus2(zahl) print(zahl+2) end
function plus3(zahl) print(zahl+3) end
-- already prints out 6,5,10
local tfunc={plus1(5),plus2(3),plus3(7)}
how can I avoid this?
how can I iterate through the functions with given parameters in the table? I would like to call the functions like:
tfunc[1]
to print out 6. But it does not work.
#pschulz, thanks to show me the way :
local tfunc = {{plus1,5},{plus2,3},{plus3,7}}
tfunc[i][1](tfunc[i][2])
allows to iterate with index i through the different functions with different args. The trick is tables with function name and args inside the table.
In you table, you are currently storing nothing (or three nil). The table takes the return value of the function and since you are returning nothing, it gets nil.
What you have to do is store functions:
local tfunc = {
plus1,
plus2,
plus3
}
No you can call your functions like this:
tfunc[1](5)
On iterating: If i understand correctly, you want to do the following:
local tfunc = {
plus1,
plus2,
plus3
}
local tvalues = { 5, 3, 7 }
for i, func in ipairs(tfunc) do
func(tvalues[i])
end
So you have to save your values in another table. There are more elegant ways to do this, i suggest you have a reading on closures.
local tfunc={plus1(5),plus2(3),plus3(7)}
Here you call the functions inside the table constructor.
So once you create your table you will print those values. As your function does not return anything tfunc remains empty.
You can either store the function call as a string and let Lua execute that string or you can save the function in the table without calling it. Then you need some way to get the function parameter zahl into your function call.
To me what you want to do makes no sense.
If you want to call it like tfunc[1] it will always print 6. So why not just call print(6)?
If you want to add 3 to a number you want to print, just call print(number + 3) e.g.
Your code will remain more readable and easier to understand if you don't move simple arrithmetics into an extra function.
For example, I have a table
table.insert( t, 1, function()
print ("rock");
end );
Is there any way to get function name from this table. I know that I can store name like a key, but what if I want to keep numeric index and also I want to know function name?
Is there any way to do it?
Thanks, on advance.
Say you have this code:
t = {}
x = 5
table.insert(t, 1, x)
t would then be {[1] = 5}. "5" is just a number - it has no name, and isn't associated with the variable "x"; it's a value.
In Lua, functions are treated exactly the same way, as values:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, x)
The value of x is not associated with x in any way, shape, or form. If you want to manually name a function, you can do it by wrapping the function in a table, for example:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, {
name = "MyFunctionName",
func = x
})
That is how you would do it!
...unless..
..you break the rules!
When Lua was developed, the developers realised that the anonymous nature of functions would make productive error messages difficult to produce, if not impossible.
The best thing you'd see would be:
stdin: some error!
stdin: in function 'unknown'
stdin: in function 'unknown'
So, they made it so that when Lua code was parsed, it would record some debug information, to make life easier. To access this information from Lua itself, the debug library is provided.
Be very careful with functions in this library.
You should exert care when using this library. The functions provided here should be used exclusively for debugging and similar tasks, such as profiling. Please resist the temptation to use them as a usual programming tool: they can be very slow. Moreover, several of these functions violate some assumptions about Lua code (e.g., that variables local to a function cannot be accessed from outside or that userdata metatables cannot be changed by Lua code) and therefore can compromise otherwise secure code.
To achieve your desired effect, you must use the debug.getinfo function; an example:
x = function()
print("test!")
print(debug.getinfo(1, "n").name)
end
x() -- prints "test!" followed by "x"
Unfortunately, the form of debug.getinfo that operates directly on a function doesn't fill the name argument (debug.getinfo(x, "n").name == nil) and the version above requires you to run the function.
It seems hopeless!
...unless..
..you really break the rules.
The debug.sethook function allows you to interrupt running Lua code at certain events, and even change things while it's all happening. This, combined with coroutines, allows you to do some interestingly hacky stuff.
Here is an implementation of debug.getfuncname:
function debug.getfuncname(f)
--[[If name found, returns
name source line
If name not found, returns
nil source line
If error, returns
nil nil error
]]
if type(f) == "function" then
local info = debug.getinfo(f, "S")
if not info or not info.what then
return nil, nil, "Invalid function"
elseif info.what == "C" then
-- cannot be called on C functions, as they would execute!
return nil, nil, "C function"
end
--[[Deep magic, look away!]]
local co = coroutine.create(f)
local name, source, linedefined
debug.sethook(co, function(event, line)
local info = debug.getinfo(2, "Sn")
name = info.namewhat ~= "" and info.name or nil
source, linedefined = info.short_src, info.linedefined
coroutine.yield() -- prevent function from executing code
end, "c")
coroutine.resume(co)
return name, source, linedefined
end
return nil, nil, "Not a function"
end
Example usage:
function test()
print("If this prints, stuff went really wrong!")
end
print("Name = ", debug.getfuncname(test))
This function isn't very reliable - it works sometimes, and doesn't others. The debug library is very touchy, so it's to be expected.
Note that you should never use this for actual release code! Only for debugging!
The most extreme case that is still acceptable is logging errors on piece of released software, to help the developer fix issues. No vital code should depend on functions from the debug library.
Good luck!
The function hasn't got any name. If you want you can assign it to a named variable:
theFunction = t[1]
-- Call it:
theFunction()
If what you want is storing a named function to the table, define it beforehand and use its name to store it:
theFunction = function()
print ("rock");
end
table.insert(t, 1, theFunction)
If this is not what you meant, give more details; for example how you would like to access the function. You're question is a bit misty.
The thing is table.insert considers the table as a sequence, only with numeric keys.
If you want to be able to call the function as t.fun() you'll have to use the table as an associative array and hence use a string as key. (BTW any type except nil or NaN are allowed as key)
t={}
t['MyFun']=function print'foo' end
t.myFun() -- uses syntactic sugar for string keys that are valid identifiers.
You might also notice that functions are passed by reference. So all functions are actually anonymous, and are just stored as a value to a certain key or variable.
You can store the names in a separate table.
functions = {}
functionNames = {}
function addFunction(f, name)
table.insert(functions, f)
functionNames[name] = f
end
To get the function, you can use the index. Once you have the function, you can get its name from function_names:
f = functions[3]
name = functionNames[f]
Good luck!
I'm trying to get a handle on how OOP is done in Lua, and I thought I had a simple way to do it but it isn't working and I'm just not seeing the reason. Here's what I'm trying:
Person = { };
function Person:newPerson(inName)
print(inName);
p = { };
p.myName = inName;
function p:sayHello()
print ("Hello, my name is " .. self.myName);
end
return p;
end
Frank = Person.newPerson("Frank");
Frank:sayHello();
FYI, I'm working with the Corona SDK, although I am assuming that doesn't make a difference (except that's where print() comes from I believe). In any case, the part that's killing me is that inName is nil as reported by print(inName)... therefore, myName is obviously set to nil so calls to sayHello() fail (although they work fine if I hardcode a value for myName, which leads me to think the basic structure I'm trying is sound, but I've got to be missing something simple). It looks, as far as I can tell, like the value of inName is not being set when newPerson() is called, but I can't for the life of me figure out why; I don't see why it's not just like any other function call.
Any help would be appreciated. Thanks!
Remember that this:
function Person:newPerson(inName)
Is equivalent to this:
function Person.newPerson(self, inName)
Therefore, when you do this:
Person.newPerson("Frank");
You are passing one parameter to a function that expects two. You probably don't want newPerson to be created with :.
Try
Frank = Person:newPerson("Frank");
I've never used actionscript before, and but I've just had to dive into it in order to get a map working.
I'm using the following code to add a map marker, replacing a previous one if one exists:
public var tracer:Array = new Array();
public var tracerLng:Number = 0;
for ( var i : Number=1 ; i<64000 ; i++)
{
//Check if there is already a marker, if so get rid of it
if(tracerLng > 0) {
map.removeOverlay(tracer[0]);
tracer[0] = null;
tracer.pop();
}
// Set up a marker
var trackMrk:Marker = new Marker(
new LatLng(_lat, _lng),
new MarkerOptions({
strokeStyle: new StrokeStyle({color: 0x987654}),
fillStyle: new FillStyle({color: 0x223344, alpha: 0.8}),
radius: 12,
hasShadow: true
})
);
//Add the marker to the array and show it on the map
tracerLng = tracer.push(trackMrk);
map.addOverlay(tracer[0]);
}
My first problem is that running this code (The 64000 repeats are for testing, the final application won't need to be run quite THAT many times). Either way, memory usage increases by about 4kB/s - how do I avoid that happening?
Secondly - could anyone advise me on how to make that program more graceful?
Thanks in advance for advice
This isn't a memory leak, it's probably the result of created events - enter frames, mouse events, custom events etc. Provided that your memory doesn't keep going up and up forever, it's nothing to be worried about - it'll get garbage collected in due course.
Some points on your code:
The tracer Array doesn't seem to do anything - you only seem to be holding one thing in there at a time, so an array makes no sense. If you need an Array, use Vector instead. It's smaller and faster. More so if you create one with a specific length.
Don't create a new Marker unless you need one. Reuse old objects. Learn about object pooling: http://help.adobe.com/en_US/as3/mobile/WS948100b6829bd5a6-19cd3c2412513c24bce-8000.html or http://lostinactionscript.com/2008/10/30/object-pooling-in-as3/
The LatLng and MarkerOptions (including the stroke and fill objects) don't seem to change (I'm assuming the LatLng object lets you set a new position). If that's the case, don't create new ones when you don't need to. If you need to create new ones, StrokeStyle and FillStyle seem good candidates for a "create once, use everywhere" policy.
Create a destroy() function or similar in your Marker class and explicitly call it when you need to delete one (just before setting it to null or popping it from the array). In the destroy() function, null out any parameters to non-base classes (int, Number, String etc). Garbage collection runs using a reference counting method and a mark and sweep method. Ideally, you want to run everything using reference counting as it's collected quicker and stops any stalls in your program.
I explain memory management in AS3 a bit more here: http://divillysausages.com/blog/tracking_memory_leaks_in_as3
Also included is a class that helps you track down memory leaks if there are any