I am trying to learn a bit about Vala and wanted to create a Calculator to test how Gtk worked. The problem is that I coded everything around the supposition that there would be a way to parse a string that contained the required operations. Something like this:
string operation = "5+2/3*4"
I have done this with Python and it is as simple as using the compilers parser. I understand Python is math oriented, but I thought that perhaps there would be Vala library waiting for me as an answer... I haven't found it if it does exist, but as I was looking at the string documentation, I noticed this part:
/* Strings prefixed with '#' are string templates. They can evaluate
* embedded variables and expressions prefixed with '$'.
* Since Vala 0.7.8.
*/
string name = "Dave";
println (#"Good morning, $name!");
println (#"4 + 3 = $(4 + 3)");
So... I thought that maybe there was a way to make it work that way, maybe something like this:
stdout.printf(#"$(operation)")
I understand that this is not an accurate supposition as it will just substitute the variable and require a further step to actually evaluate it.
Right now the two main doubts I am having are: a) Is there a library function capable of doing this? and b) Is it possible to work out a solution using string templates?
Here's something I found that would do the work. I used the C++ libmatheval library, for this I first required a vapi file to bind it to Vala. Which I found here. There are a lot of available vapi files under the project named vala-extra-apis, and they are recognized in GNOME's Vala List of Bindings although they are not included at install.
You could parse the expression using libvala (which is part of the compiler).
The compiler creates a CodeContext and runs the Vala parser over a (or several) .vala file(s).
You could then create your own CodeVisitor decendant class that visits the necessary nodes of the parse tree and evaluates expressions.
As far as I can see there is no expression evaluator that does this, yet. That is because normally vala code is translated to C code and the C compiler then does compile time expression evaluation or the finished executable does the run time evaluation.
Python is different, because it is primarily a scripting language and has evaluation build directly into the runtime / interpreter.
Related
I find Erlang's module arity import /n where n is the number of arguments rather bizarre.
In Java and various other languages you can do something like:
import static com.stuff.Blah.myFunction;
Which will import all overloaded Blay.myFunction(..) regardless of parameters.
Besides I guess being explicit why did the language designers decide this was a good idea (I'm not trying to criticize the language... just curious)?
Does it have to do with code swapping?
Or does it have to do with hiding guard methods for recursion? If so why not allow arity on export but no need for arity on import?
Why would I want to be that explicit? That is import the two argument function but not the the three argument of myFunction?
You should be aware of what importing functions in Erlang really does. It is a pure textual transformation. If I do an -import(foo, [bar/1,baz/2]). it means that when I write a call like bar(5) or baz(a, 3) the compiler transforms these to foo:bar(5) and foo:baz(a, 3). That is all it does, nothing else. It doesn't check anything:
It doesn't check if the module foo contains the functions bar/1 or baz/2.
It doesn't even check if the module foo exists.
Really all it does is hide that you are calling a function in another module. That is why the recommendation from experienced Erlangers is "don't use it". It was a mistake. Unfortunately it is much easier to add stupid things than to get rid of them so we were never able to remove it.
"Does it have to do with code swapping?"
Yes, sort of. The unit of all code handling in Erlang is the module. So you compile modules, load modules, purge and delete modules. This means that there are no inter-module dependencies at all in the system and the compiler makes no assumptions about other modules when it is compiling a module. No assumptions are made that the environment in which a module is compiled will be the same in which it is run. That is why it is at runtime the system checks whether the function you are trying to call in another exists, or even if the module itself exists. That is why the import was a purely textual transformation.
Erlang was originally developed in Prolog.
In Prolog, the arity adds additional meaning to what you consider to be the 'arguments, as I understand from a function' in a procedural programming language. But that model does not apply here.
The so-called clauses 'married(X,Y).' and 'married(X,Y,Z).' imply a different kind of relationship 'married', which can be declared as married/2 and married/3.
In procedural programming, 'add(a,b)' or 'add(a,b,c)' are intended to generate the addition of a different number of arguments. That's not immediately the case in Prolog, where it is possible to have the relationship 'a and b, added' or 'a, b and c, added' mean something else. Needless to say, Prolog allows you to declare 'add' as you would expect a function would do. But it allows for more. More available meaning, means more need to control it.
And as in any module system, selecting what you want to expose to external clients makes sense: hence the declaration of arity.
Does it have to do with code swapping?
Kind of. The modules in Erlang are compiled separately (which is part of what allows code swapping), unlike Java classes, so the compiler doesn't know how many versions of the imported function with different arities exist. It could assume that all calls of a function with the given name come from the same module, of course, but the designers likely decided it wasn't particularly useful.
In fact, you rarely want to use imports at all, at least in my experience, just as you rarely use static imports in Java. Just write module:function, like Class.staticMethod.
Or does it have to do with hiding guard methods for recursion?
No, since not importing functions doesn't hide them in any way.
In the documentation it says, 'source' can be either str or AST object
When trying to compile my ast root:
dl = compile(newRoot, '<string>', 'eval')
I get this Exception:
expected str, got Module
I am using the last version of IronPython.
Is there an idea why this does not work? all the examples I found seem to do it this way with no issues.
Is there a workaround to compile an AST object?
Thanks!!!!
PD: I found this issue but seems to have no activity: http://ironpython.codeplex.com/workitem/32526
First off, IronPython does not support this.
It's actually quite hard to support in IronPython (and I didn't know it needed to be supported until today). IronPython's _ast module is a wrapper around its own AST, and currently only implements conversion from IronPython AST => CPython AST, but not the reverse. It's a fair bit of (honestly, quite tedious) work, so I'm not sure when it will get fixed.
If there's a popular program or library that's broken because of this that moves it up the priority list, and patches are always welcome.
It only recognizes top-level non-function value declarations.
e.g. let a = 2
and doesn't produce documentation for functions or type definitions.
I've checked the xml documentation file and it has all the /// comments I put in the source, but none of them (except for the top level values) show up in the resulting html.
Yes, using C#-centric tools for F# documentation generation is usually pretty horrible. We started an alternative project a while ago, but it is not yet as mature as SandCastle: http://bitbucket.org/IntelliFactory/if-doc
I'm using a closed-source application that loads Lua scripts and allows some customization through modifying these scripts. Unfortunately that application is not very good at generating useful log output (all I get is 'script failed') if something goes wrong in one of the Lua scripts.
I realize that dynamic languages are pretty much resistant to static code analysis in the way C++ code can be analyzed for example.
I was hoping though, there would be a tool that runs through a Lua script and e.g. warns about variables that have not been defined in the context of a particular script.
Essentially what I'm looking for is a tool that for a script:
local a
print b
would output:
warning: script.lua(1): local 'a' is not used'
warning: script.lua(2): 'b' may not be defined'
It can only really be warnings for most things but that would still be useful! Does such a tool exist? Or maybe a Lua IDE with a feature like that build in?
Thanks, Chris
Automated static code analysis for Lua is not an easy task in general. However, for a limited set of practical problems it is quite doable.
Quick googling for "lua lint" yields these two tools: lua-checker and Lua lint.
You may want to roll your own tool for your specific needs however.
Metalua is one of the most powerful tools for static Lua code analysis. For example, please see metalint, the tool for global variable usage analysis.
Please do not hesitate to post your question on Metalua mailing list. People there are usually very helpful.
There is also lua-inspect, which is based on metalua that was already mentioned. I've integrated it into ZeroBrane Studio IDE, which generates an output very similar to what you'd expect. See this SO answer for details: https://stackoverflow.com/a/11789348/1442917.
For checking globals, see this lua-l posting. Checking locals is harder.
You need to find a parser for lua (should be available as open source) and use it to parse the script into a proper AST tree. Use that tree and a simple variable visibility tracker to find out when a variable is or isn't defined.
Usually the scoping rules are simple:
start with the top AST node and an empty scope
item look at the child statements for that node. Every variable declaration should be added in the current scope.
if a new scope is starting (for example via a { operator) create a new variable scope inheriting the variables in the current scope).
when a scope is ending (for example via } ) remove the current child variable scope and return to the parent.
Iterate carefully.
This will provide you with what variables are visible where inside the AST. You can use this information and if you also inspect the expressions AST nodes (read/write of variables) you can find out your information.
I just started using luacheck and it is excellent!
The first release was from 2015.
In his article The Nature of Lisp, Slava Akhmechet introduces people to lisp by using Ant/NAnt as an example. Is there an implementation of Ant/NAnt in lisp? Where you can use actual lisp code, instead of xml, for defining things? I've had to deal with creating additions to NAnt, and have wished for a way to bypass the xml system in the way Slava shows could be done.
Ant is a program that interprets commands written in some XML language. You can, as justinhj mentioned in his answer use some XML parser (like the mentioned XMLisp) and convert the XML description in some kind of Lisp data and then write additional code in Lisp. You need to reimplement also some of the Ant interpretation.
Much of the primitive stuff in Ant is not needed in Lisp. Some file operations are built-in in Lisp (delete-file, rename-file, probe-file, ...). Some are missing and need to be implemented - alternative you can use one of the existing libraries. Also note that you can LOAD Lisp files into Lisp and execute code - there is also the REPL - so it comes already with an interactive frontend (unlike Java).
Higher level build systems in Common Lisp usually are implementing an abstraction called 'SYSTEM'. There are several of those. ASDF is a popular choice, but there are others. A system has subsystems and files. A system has also a few options. Its components also have options. A system has either a structural description of the components, a description of the dependencies, or a kind descriptions of 'actions' and their dependencies. Typically these things are implemented in an object-oriented way and you can implement 'actions' as Lisp (generic) functions. Lisp also brings functions like COMPILE-FILE, which will use the Lisp compiler to compile a file. If your code has, say, C files - you would need to call a C compiler - usually through some implementation specific function that allows to call external programs (here the C compiler).
As, mentioned by dmitry-vk, ASDF is a popular choice. LispWorks provides Common Defsystem. Allegro CL has their own DEFSYSTEM. Its DEFSYSTEM manual describes also how to extend it.
All the Lisp solution are using some kind of Lisp syntax (not XML syntax), usually implemented by a macro to describe the system. Once that is read into Lisp, it turns into a data representation - often with CLOS instances for the system, modules, etc.. The actions then are also Lisp functions. Some higher-order functions then walk over the component graph/tree and execute actions of necessary. Some other tools walk over the component graph/tree and return a representation for actions - which is then a proposed plan - the user then can let Lisp execute the whole plan, or parts of the plan.
On a Lisp Machine a simple system description looks like this:
(sct:defsystem scigraph
(:default-pathname "sys:scigraph;"
:required-systems "DWIM")
(:serial "package" "copy" "dump" "duplicate" "random"
"menu-tools" "basic-classes" "draw" "mouse"
"color" "basic-graph" "graph-mixins" "axis"
"moving-object" "symbol" "graph-data" "legend"
"graph-classes" "present" "annotations" "annotated-graph"
"contour" "equation" "popup-accept" "popup-accept-methods"
"duplicate-methods" "frame" "export" "demo-frame"))
Above defines a system SCIGRAPH and all files should be compiled and load in serial order.
Now I can see what the Lisp Machine would do to update the compiled code:
Command: Compile System (a system [default Scigraph]) Scigraph (keywords)
:Simulate (compiling [default Yes]) Yes
The plan for constructing Scigraph version Newest for the Compile
operation is:
Compile RJNXP:>software>scigraph>scigraph>popup-accept-methods.lisp.newest
Load RJNXP:>software>scigraph>scigraph>popup-accept-methods.ibin.newest
It would compile one file and load it - I have the software loaded and changed only this file so far.
For ASDF see the documentation mentioned on the CLIKI page - it works a bit different.
Stuart Halloway's upcoming book Programming Clojure goes through the construction of Lancet throughout the book as an example app. Lancet is a Clojure build system which (optionally) integrates directly with Ant. Source code and examples are available.
If all you want to do is generate Ant XML files using Lisp code, you could use something like clj-html for Clojure or CL-WHO for Common Lisp. Generating XML from Lisp s-exps is fun and easy.
Common Lisp's ASDF (Another System Definition Facility) is analogous to Make/Ant (but not a full analogue — it is aimed at building lisp programs, not generic systems like make or ant). It is extensible with Lisp code (subclassing systems, components, adding operations to systems). E.g., there is an asdf-ecs extensions that allows including (and compiling) C source files into system.
Perhaps you could define things in lisp and convert them to XML at the point you pass them to NAnt.
Something like XMLisp makes it easier to go back and forth between the two representations.
Edit: Actually, xml-emitter would make more sense.