Okay so, if I am not mistaken, in C or C++ we use the code below to shorten or substitute the statement to a different one. So you can just write P rather than printf as a command right?
#define P printf
Then how do we do that in Java?
Java does not have macros, or a pre-processing step.
One must realize that with every programming language comes its own set of tools.
Many times MACROS are used where C++ templates or Java generics can be used, for example in case of a MAX macro.
If you really want to have a pre processing state, you should consider inserting a step to your build system (i.e - maven pluggin) that will go over your "Java code with macros", generate real Java files from it (similar to how inline functions behave in C++), and then compile the generated java code.
You can find examples to it for example in case where Java code is generated from XSD or other schemas, so theoretically, why not generate it from "Java with macros code"?
If you look for example at project Lombok you will see they introduce a "properties" systax to Java, but in fact they just introduced IDE plugins (so the code does not look "broken" or "in error" when you code with your favorite IDE), and they introduced mavan steps/goals so you can actually build something developed with Lombok.
Maybe you should adopt a similar approach, if this is that crucial for you (actually in past , prior to JDK 5, this is how "annotations" were used in some frameworks, but you should have a really good reason to do that in your code).
Java does not have a preprocessor step like the languages you enumerated (the C macro language is handled by the preprocessor). You can make a static final function, or you could use cpp to pre-process your Java src (which I would not recommend because it wouldn't work with standard tools). Another somewhat similar alternative (but only in the sense of being able to omit a class name by adding a symbol to a local namespace) might be the static import.
import static java.lang.System.out;
// ...
out.println("Hello, World"); // <-- System.out.println
java doesn't have any internal preprocessor but if it is strongly desired by project (usually by mobile project where needed small code corrections for many destination devices) then external tools can be used, somebody uses even C/C++ preprocessor to preprocess sources, I use my own java-comment-preprocessor but anyway all java preprocessors, I have seen, don't allow such tricks as C/C++ preprocessor does, because preprocessor directives are not supported on the java language level
Related
Problem
I am developing a Java stand-alone static testing tool for C++ projects. In this tool, I need to get name resolution inside a project.
For example, given two statements in a function:
int x = 0;
int y = x + 1;
By using name resolution on the variable x of the second statement, I detect that it is declared at the first one.
Current solution
Firstly, I used Eclipse CDT plugin (only a part of CDT) to create abstract syntax trees (AST). More clearly, each of source code files in the testing project is analyzed to construct a corresponding AST. However, these ASTs do not contain name resolution. Therefore, I have to analyze AST to detect name resolution. My current solution seems to be good, but for large-scale projects and complex structures, it definitely fails.
Later, I have known that information about name resolution could be obtained automatically by using Eclipse CDT. But I need to create a stand-alone tool (outside Eclipse), it means that I could not integrate my tool into CDT.
I have known that C++ uses static name resolution rather than dynamic approach. So, this information about name resolution could be collected. Can you suggest me any further ideas to overcome my issue?
Updated (based on recommendations below)
Some suggest me as follows, and my response.
+ Use Clang
It is true that Clang supports to analyse C++ files (and C files also), and there is no denying that Clang is a good choice. However, my language I want to use is Java. Currently, I only find one (i.g., Eclipse CDT plugin). As I said, CDT plugin does not support name resolution when I try to use it outside Eclipse CDT IDE.
My current Java stand-alone tool, namely CFT4Cpp, uses CDT plugin to parse C/C++ program. Due to the limit of CDT plugin, I have analyzed name resolution by using some simple algorithms. However, these algorithms fail when analyzing complex projects in terms of syntaxes.
C++ is a very complex programming language (and different of C). Parsing it is a very difficult task (many years of work - perhaps a lifetime if working alone - if you do that from scratch).
So build your tool above some existing C++ parsing technology. You could use GCC, perhaps thru GCC plugins, or Clang (see this), or Edison C++ frontend etc. Free software C++ compilers are huge beasts (several millions of lines) continuously evolving and growing, and mastering them requires a lot of work. BTW, you could use common inter-process communication (e.g. JSONRPC or other approaches) or foreign function interfaces techniques (e.g. JNI) to use C++ compiler frameworks from Java.
However, my language I want to use is Java.
Be pragmatic. So code a small part in C++ (above existing parsers, e.g. from C++ compilers), and the rest in Java.
(for an academic prototype, using some inter-process communication between an adapted compiler in C++ and some tool in Java is probably the less difficult; however, you will have to code several thousands lines on the compiler side in C++, since C++ is complex; and you'll need more on your Java side; BTW, you probably need a bit of practice in C++ to be able to design useful things for it...)
(since you probably won't find complete C++ compilers or front-ends in Java)
Even if building your thing above an existing C++ parser, the task is not easy and could consume several months of your time. And existing C++ parsers are evolving (e.g. the internal representations of GCC is slightly changing from one version to the next one). So you need to budget the evolution of these parsers.
And parsing C++ is itself an ill defined task (think of preprocessing, template expansions, etc....). You need to define on what form of C++-related code representation you want to work on. Of course the C++ standard have several releases, etc.
Perhaps you should consider asking your manager (or get some research grant, if you are academic) to work full time on that for several years. But ask yourself if it is worthwhile....
Alternatively, if you restrict yourself to one C++ project, consider instead defining some project-specific conventions, generating some C++ code and some tests in it. YMMV.
Another approach (which works on Linux, but probably not everywhere else) is to ask your user to compile with debug information enabled (e.g. with g++ -g if he uses GCC) and to parse DWARF debug information.
BTW, I did work on similar goals: a few years ago in GCC MELT, and now in my bismon github project (temporary name, will change). Be sure to get funded for several years of work full time, since your goal is very ambitious.
There is more to using a an existing and wide-spread compiler over your own solution then the complexity involved in the implementation.
C++ is now an ever-changing language. Since C++11 the road map is a new version of the standard every 3 years. And they sicked with it: we have C++11, C++14, C++17 and C++20 is on track.
You will have a very very difficult and time consuming challenge ahead just for staying up with the changes in standard.
For example I show you just 1 change per version that you would need to add support for. Can you / are you willing to support each new standard version in its entirely? Or are you going to end up with an application/tool that by the time it gets out of development is already obsolete?
C++98:
int x = 0;
int y = x + 1;
C++11:
auto x = 0;
auto y = x + 1;
C++14
[](auto x) { auto y = x; }
C++17
if (const auto [iter, inserted] = mySet.insert(value); inserted)
C++20 hopefully this:
template <class T, class F, class P>
requires requires(T x, F f, P p) {
f(x);
{p(f(x))} -> bool;
}
auto bar(T x, F f, P p)
{
//
}
With a solution based on an compiler like gcc or clang you have all these taken care of by the compiler itself. All you need to do is use it for your own purpose.
I have a compiler for a domain specific language that outputs a .net dll (that can then be used to do whatever the DSL said it should). It works well under .net but now I need to make the compiled dll functionality accessible from Java. The interface changes depending on the DSL, much like it would if I was implementing an F# type provider.
Ideally, I would like something along the lines of Reflection.Emit except that it would generate Java bytecode. It is important that the end-user can debug their Java code that uses my generated library from a Java GUI, so I don't think I can just use IKVM to instead include the Java code in .net. I also cannot use a commercial product such as JNBridge because all the users would need to install it, and call it every time their DSL code changes.
Is there a better solution than generating a .java file in text format and compiling it with a Java compiler? The .java file would just be a light-weight interface talking to the .net dll over some IPC mechanism (perhaps a named pipe), and its purpose would be to provide a typesafe interface similar to what would be seen from a .net application (except with indexers, getters, setters, overloads, etc replaced with some sort of horribly verbose syntax). Many thanks.
Java native interface is a way to call native code from Java (That dll isn't running on the JVM, thats for sure). Throw your dreams of "Write once run anywhere" in the bin now.
If you want to use dlls then you have to use JNI (or something similar or based on JNI like jni4net). It's not as pleasant as say, using c++ from c#, but it's pretty doable and far and away the best way to use dlls from java (I think the second best is re-writing the native code).
Alternatively you could run a windows process alongside your java app and soap/json/namedpipes/etc between the two, is that what you suggest in the last paragraph?
This would be odd for a small solution, but for a larger modular project it's not so crazy. I would recommend using sockets to communicate between the two, because I think sockets are easiest. It says client/server in the example, but it could be two processes (java and f#). ... This causes problems for performance, synchronisation, firewalls etc.. ahhh, just use JNI.
I was kind a curious if it was possible to do assembly programming in a similar fashion of using NASM in C.
After quick Google search to see if it was possible to do assembly language programming on the JVM and was surprised to find some results.
Has anyone tried doing something like this before?
I'm also wondering if there are any support assembly support for Clojure or Scala.
Invoking Assembly Language Programming from Java
minijavac : Not in English but it looks like it using some kind of NASM support.
Assembly is usually used in C so that a) you can access instructions C doesn't generate or b) lower level performance tuning.
As byte code is designed for Java,
there aren't any useful byte code instructions it doesn't generate
The JVM looks for common patterns in byte code generated by the compiler and optimises for those. This means if you write the byte code yourself it is more likely to be less optimised i.e.
slower, unless it is the same as what the compiler would produce.
Write a JNI library in C with inline assembly in it.
In theory, you could write a JNI-compliant library in pure assembly, but why bother?
I'd like to point to another solution: generating assembly code at runtime from your java program.
Some (long) time ago there was a project called softwire, written in c++, that did exactly that. It (ab)used (method and operator) overloading to create some kind of c++ DSL that closely resembles x86 ASM, and which behind the scene would assemble the corresponding assembly. The main goal was to be able to dynamically assemble an assembly routine customized for specific configuration, while eliminating nearly all the branchings (the routine would be recompiled if the confiugration changed).
This was an excellent library and the author used to to great effect to implement a software renderer with shading support (shaders were dynamically translated to x86 assembly and the assembled, all at runtime), so this was not just a crazy idea. Unforuntately he was hired by a company and the library acquired in the process.
Today, to follow such a route you could create a JNI binding to DynAsm (that alone is probably no small task) and use it to assemble at runtime. If you are willing to use scala over java, you can even relatively easily create a DSL ala softwire, that will under the hood generate the assembly source code and pass it to DynASM.
Sounds like fun :-)
No reason to be bored anymore.
Are you looking for something like jasmin project? Because,for some reason for me, minijava always reminds me of jasmin parser...
I'm looking for a Java macro language that provides for convenient ways of doing closures (that compile to anonymous inner classes) and list comprehension (that compiles down to basic java loops).
An example of the kind of thing I'm looking for would be Xtend2 http://www.eclipse.org/Xtext/#xtend2
But I want something for general purpose programming (Xtend2 is very specific DSL for Xtext and has a ton of dependencies). Maybe even something that would let me define multiple classes in a single file (which would then get split up into two separate files by the pre-processor).
Does anything like this exist?
Edited to add:
I'm doing Android development so any alternatives have to generate either valid Java source or the byte code has to be compatible with the dalvik recompiler.
Mmm, there used to be the JSE, which was tremendous fun, back in the day.
Mirah is cool, but not ready for primetime, IMO.
You can do a lot with smart templating, although your source view is the Java.
There's a post on SO about using XTend on Android from a few days ago, too.
Frege produces java source code.
I do not know whether dalvik would like it. (But I would be interested to hear ...)
And, of course, you have some runtime library code.
That being said, there are a number of other projects that do closures etc. in java, for example: lambdaj
If I wanted to create a new language for Java I should make a compiler that is able to generate the byte-code compatible with the JVM spec, right? and also for the JDK libraries?
Where can I find some info?
Thanks.
Depends what you mean by "create a new language for Java" -- do you mean a language that compiles to bytecode and the code it generates can be used from any Java app (e.g. Groovy) or an interpreted language (for which you want to write a parser in Java)?
If it is the former one then #Joachim is right, look at the JVM spec; for the latter look at the likes of JavaCC for creating a parser for your language grammar.
I would start with a compiler which produced Java source. You may find this easier to read/understand/debug. Later you can optimise it to produce byte code.
EDIT:
If you have features which cannot be easily translated to Java code, you should be able to create a small number of byte code classes using Jasmin with all the exotic functionality which you can test to death. From the generated Java code this will look like a plain method call. The JVM can still inline the method so this might not impact performance at all.
The Java Virtual Machine Spec should have most of what you need.
An excellent library for bytecode generation/manipulation is ASM: http://asm.ow2.org.
It is very versatile and flexible. Note however that it's API is based on events (similar to Sax parsers) - it reads .class files and invokes a method whenever it encounters a new entity (class declaration, method declaration, statements, etc.). This may seem a bit awkward at first, but it saves a lot of memory (compared to the alternative: the library read the input, spits out a fully-evolved tree structure and then you have to iterate over it).
I don't think this will help much practically, but it has a lot of sweet theoretical stuff that I think you'll find useful.
http://www.codeproject.com/KB/recipes/B32Machine1.aspx