Page 1 of 3
LCContextGet
Posted: Tue Jun 04, 2013 2:15 am
by monte
Proposing a new function for lcidl externals....
The function would work like LCObjectGet but allow us to get global and local properties.
Use Case 1
I'm implementing mergSocket and currently have a parameter for the equivalent of allowDatagramBroadcasts on mergSocketSendDatagram. What would be good is if I could read the value of that global property from the environment... I'm sure there are other better use cases and this one is a bit trivial...
BTW is there any way for a LC socket to join multicast groups? I can't see any docs for it... If not then I won't bother implementing that for iOS...
Re: LCContextGet
Posted: Wed Jun 05, 2013 11:07 pm
by LCMark
In terms of context-local properties then they would probably be better added as a collection of new LCContext* functions - maybe something like:
Code: Select all
LCContextCaseSensitive(bool *)
LCContextConvertOctals(bool *)
LCContextItemDelimiter(unsigned int options, void *)
LCContextLineDelimiter(unsigned int options, void *)
LCContextColumnDelimiter(unsigned int options, void *)
LCContextRowDelimiter(unsigned int options, void *)
These accessors are already implemented in externalv1.cpp in the engine (via the context_query call), so it would be an easy case of mutatis-mutandis in Support.mm in lcidlc. Here 'options' is so that you can specify the output format of the request - this is 'forward-compatibility-with-unicode' pedanticism to a certain degree - it would go with an kLCValueOptionAsChar option. The stub in support.mm would just ignore this for now. (The rationale here is that we might get to Unicode support in the engine before the new Extensions API, and this provision would mean existing externals would still work the same, and be able to be upgraded to Unicode support).
For global properties the situation is a little trickier, mainly because they aren't defined relative to a table, but as discrete syntax (the MCProperty class). I'd always envisioned handling this by adding expression evaluation support:
Code: Select all
LCContextEvaluate(const char *expression, unsigned int options, void *value)
Here 'options' would be the same as LCObjectGet, performing appropriate type conversions on the result of the evaluation. Adding this would require a new method in the externalv1.cpp interface - which just needs to do a similar thing to eval_expr() in externalv0.cpp.
Along this vein, the (full) API I'd always considered for more general script execution (but never gotten around to implementing) was something along the lines of:
Code: Select all
LCContextEvaluate(const char *expression, unsigned int options, void *value) -- evaluate the expression in the current context
LCContextExecute(const char *script) -- execute the given sequence of commands in the current context
LCScriptCompile(const char *script, unsigned int options, LCScriptRef *r_syntax) -- pre-compile the given expression or commands, 'options' specifies the type (expression or commands).
LCScriptRetain(LCScriptRef script)
LCScriptRelease(LCScriptRef script)
LCContextEvaluateScript(LCScriptRef script, unsigned int options, void *value)
LCContextExecuteScript(LCScriptRef script)
LCContextResult(unsigned int options, void *value)
LCContextIt(unsigned int options, void *value)
The point here is that you can 'precompile' scripts and re-use them again and again which adds efficiency (particularly for longer scripts and expressions).
Re: LCContextGet
Posted: Wed Jun 05, 2013 11:22 pm
by LCMark
Of course, I've just realized that my 'extended' API for such things is a tad pie-in-the-sky at the moment because it would require a lot of work to handle compiling scripts in an isolated environment - due to variable declarations and having to match them up to context!
Still:
Code: Select all
LCContextEvaluate(const char *expression, unsigned int options, void *value) -- evaluate the expression in the current context
LCContextExecute(const char *script) -- execute the given sequence of commands in the current context
LCContextResult(unsigned int options, void *value)
Are all within easy reach

Re: LCContextGet
Posted: Wed Jun 05, 2013 11:23 pm
by LCMark
BTW is there any way for a LC socket to join multicast groups? I can't see any docs for it... If not then I won't bother implementing that for iOS...
Am I allowed to ask what a multicast group is?

Re: LCContextGet
Posted: Wed Jun 05, 2013 11:37 pm
by monte
Am I allowed to ask what a multicast group is?
http://en.wikipedia.org/wiki/IP_multicast
Multiple servers join the group so they get any packets sent to that IP
Re: LCContextGet
Posted: Wed Jun 05, 2013 11:40 pm
by monte
All looks good.... Now that you mention It I think it would be nice if we could set both the result and it... both in externals and scripts...
Re: LCContextGet
Posted: Thu Jun 06, 2013 8:58 am
by LCMark
@monte: Am poking around in lcidlc today - am happy to add the methods described above at the same time... Unless you want to?
Re: LCContextGet
Posted: Thu Jun 06, 2013 9:09 am
by monte
I haven't got my head around the externals interface from the other side yet... only looked at some of the externalv1 code today... I'll be interested to see what you do.. note that @mweider has a branch called LCObject with some changes while you're in there.
Re: LCContextGet
Posted: Thu Jun 06, 2013 5:22 pm
by mwieder
Yes, but my commit there is just code cleanup to remove conditionals that don't do anything. Nothing serious.
OK - I issued a pull request. Seems like the least I could do.
Re: LCContextGet
Posted: Thu Jun 06, 2013 5:47 pm
by LCMark
@mwieder: Those conditionals are part of the style of the error propagation cascade that is used a lot in the engine. Whilst the first ones don't do anything, there are there for visual consistency (all the actions are aligned at the same place), and for easier future extension - i.e. you can add a new clause before the first without having to add a new 'if'.
Re: LCContextGet
Posted: Thu Jun 06, 2013 5:51 pm
by mwieder
OK - I don't want to get in the way of code consistency. Like I said, it's a minor change.
And speaking of consistency, the conditional tests are more robust if you put them in the form
if (CONSTANT == VARIABLE)
because it ensures that you can't accidentally use a single = in the test.
Re: LCContextGet
Posted: Fri Jun 07, 2013 12:27 am
by monte
While we are looking at lcidl...
Excited by what looks like possible NSArray and NSDictionary support... A dictionary of string string or string dictionary would sort out array support in Objective-C nicely...
I'm wondering about (for some of the parameter types) supporting optional parameters without setting a default so they are just nil? This would allow us to have optional NSData...
I'm wondering about the option to specify an negative number as a default ... I think it's just a matter of adding || t_lookahead == '-' to ScannerIsNumberPrefix...
I'm wondering about optional booleans... currently I work around this by using a bool-enum to fake an optional boolean so it's not a killer if we can't do it but it would be nice

Re: LCContextGet
Posted: Fri Jun 07, 2013 9:37 am
by LCMark
Excited by what looks like possible NSArray and NSDictionary support... A dictionary of string string or string dictionary would sort out array support in Objective-C nicely...
The problem here is that I wasn't sure the best way to map things - to convert LC types to native types you need to know what type to convert to. For example, a value in an LC variable might be number, but currently encoded as a string (if you do, for example, 'put "0" into tVar[1]' rather than 'put 0 into tVar[1]'. That being said, making the mapping create (potentially recursive) arrays of strings would be relatively easy.
I'm wondering about (for some of the parameter types) supporting optional parameters without setting a default so they are just nil? This would allow us to have optional NSData...
It should be easy to do this for pointer types (that therefore have an obvious 'not passed' value - i.e. nil - as you say).
I'm wondering about the option to specify an negative number as a default ... I think it's just a matter of adding || t_lookahead == '-' to ScannerIsNumberPrefix...
That looks like an oversight - easy enough to fix.
I'm wondering about optional booleans... currently I work around this by using a bool-enum to fake an optional boolean so it's not a killer if we can't do it but it would be nice
In the refactored branch optional non-pointer types are done by passing a pointer to the value, rather than the value. i.e.
Code: Select all
int myFunc(bool *p_optional_bool, int *p_optional_int);
If the value is present, nil is passed, otherwise a pointer to a variable containing the value that was passed is given. Again, this would probably not be too much work to add...
I was hacking away at lcidlc yesterday (I use the word hacking because InterfaceGenerate.cpp is not my finest piece of work :S) and have got some more to do on it, but I can certainly see if I have time to do some of the above. You can see what I've been up to on my (runrevmark) feature-externals_api_v5 branch. (Anything I don't get around to could potentially be left for an 'easy' exercise for the Monte?

)
Re: LCContextGet
Posted: Fri Jun 07, 2013 11:43 am
by monte
The problem here is that I wasn't sure the best way to map things - to convert LC types to native types you need to know what type to convert to. For example, a value in an LC variable might be number, but currently encoded as a string (if you do, for example, 'put "0" into tVar[1]' rather than 'put 0 into tVar[1]'. That being said, making the mapping create (potentially recursive) arrays of strings would be relatively easy.
Hmm... I was expecting them all as strings
It should be easy to do this for pointer types (that therefore have an obvious 'not passed' value - i.e. nil - as you say).
Excellent
I was hacking away at lcidlc yesterday (I use the word hacking because InterfaceGenerate.cpp is not my finest piece of work :S) and have got some more to do on it, but I can certainly see if I have time to do some of the above. You can see what I've been up to on my (runrevmark) feature-externals_api_v5 branch. (Anything I don't get around to could potentially be left for an 'easy' exercise for the Monte? )
Sure... I think I'm starting to get my head around it... I might also clean up put together a pull request for my changes to lclink.sh to handle framework inclusion depending on SDK and weak linking.
Re: LCContextGet
Posted: Fri Jun 07, 2013 11:50 am
by LCMark
Hmm... I was expecting them all as strings
I think I was just over-thinking things at the time - strings it is
Sure... I think I'm starting to get my head around it... I might also clean up put together a pull request for my changes to lclink.sh to handle framework inclusion depending on SDK and weak linking.
Out of interest, what issues did you find here? I remember adding the ability to specify weak/non-weak frameworks in the .ios file, but (to be fair) it was a pretty hasty addition.