Convert an Elixir AST to an Erlang AST? Is it possible? - erlang

Is it possible to take a quoted Elixir expression (AST tree) like this:
quote do: 1 + 1
=> {:+, [context: Elixir, import: Kernel], [1, 1]}
And convert it to an Erlang AST?
I looked through the Code module as well as some of the Kernel modules looking for a function that did this but I didn't find anything. I am not even sure if this would be possible... I don't know how things like Elixir macros would be represented in Erlang AST.
Thanks in advance!

There isn't currently a public API to do so. You could look into the elixir module to know how it is done but it is private API and it can be changed any time with no guarantee of compatibility, or even removed.

For example I wrote 'gist' how it can be done - https://gist.github.com/habibutsu/bc6791d3d81b6ea54e1a
There are used two functions:
fun elixir:'string_to_quoted!'/4
fun elixir:quoted_to_erl/3

Related

Is a 'standard module' part of the 'programming language'?

On page 57 of the book "Programming Erlang" by Joe Armstrong (2007) 'lists:map/2' is mentioned in the following way:
Virtually all the modules that I write use functions like
lists:map/2 —this is so common that I almost consider map
to be part of the Erlang language. Calling functions such
as map and filter and partition in the module lists is extremely
common.
The usage of the word 'almost' got me confused about what the difference between Erlang as a whole and the Erlang language might be, and if there even is a difference at all. Is my confusion based on semantics of the word 'language'? It seems to me as if a standard module floats around the borders of what does and does not belong to the actual language it's implemented in. What are the differences between a programming language at it's core and the standard libraries implemented in them?
I'm aware of the fact that this is quite the newby question, but in my experience jumping to my own conclusions can lead to bad things. I was hoping someone could clarify this somewhat.
Consider this simple program:
1> List = [1, 2, 3, 4, 5].
[1,2,3,4,5]
2> Fun = fun(X) -> X*2 end.
#Fun<erl_eval.6.50752066>
3> lists:map(Fun, List).
[2,4,6,8,10]
4> [Fun(X) || X <- List].
[2,4,6,8,10]
Both produce the same output, however the first one list:map/2 is a library function, and the second one is a language construct at its core, called list comprehension. The first one is implemented in Erlang (accidentally also using list comprehension), the second one is parsed by Erlang. The library function can be optimized only as much as the compiler is able to optimize its implementation in Erlang. However, the list comprehension may be optimized as far as being written in assembler in the Beam VM and called from the resulted beam file for maximum performance.
Some language constructs look like they are part of the language, whereas in fact they are implemented in the library, for example spawn/3. When it's used in the code it looks like a keyword, but in Erlang it's not one of the reserved words. Because of that, Erlang compiler will automatically add the erlang module in front of it and call erlang:spawn/3, which is a library function. Those functions are called BIFs (Build-In Functions).
In general, what belongs to the language itself is what that language's compiler can parse and translate to the executable code (or in other words, what's defined by the language's grammar). Everything else is a library. Libraries are usually written in the language for which they are designed, but it doesn't necessarily have to be the case, e.g. some of Erlang library functions are written using C as Erlang NIFs.

Pretty printing AST in Rascal

I am trying to pretty print an AST generated from
createAstFromFile(|cwd:///Java/Hello.java|,true);
Have I just missed how to do this in the documentation?
If you mean unparsing an AST (getting the Java code back) you will have to write something yourself.
If you however mean printing the AST structure nicely indented, we have iprintln exactly for this purpose.
Also, for large ASTs, the REPL might not like it that much, checkout our (as pf yet) undocumented Fast print functions in util::FastPrint. The fiprintln prints to the rascal output window, which is a lot faster.
No I believe the current release does not contains this feature. If you don't rewrite the AST, you can of course get the source by reading the location, as in:
rascal>import IO;
ok
rascal>readFile(ast#\loc)
str: ...
That only works when the weather is right.. The other solutions are:
to use string templates mapping the AST back to source (simplest)
map ASTs to the Box language and call the format function (most powerful and configurable)
a hybrid of the above
I seem to recall there is a function which maps back M3 ASTs back to JDT ASTs in Java and then calls the pretty print function of JDT, but it looks like it was discontinued. In other words, here are some TODOs.

First class patterns in Erlang? (Alternatives)

Is there a way to create first-class-like patterns in Erlang? I need to be able to create and pass patterns as args to other functions but I know patterns are not first class in Erlang. I also looked at Elixir but it doesn't seem to offer anything more as far as patterns go.
I was wondering if anyone has come up with a simple solution to this problem. I was thinking of trying to implement something like this:
% Instead of using variables, we would just use uppercase atoms which would serve as vars
% A passable pattern
Pattern = {ok, 'Result'}.
% Custom function to check for matches
match(pattern, {ok, [1,2,3]}). % => true
I am new to Erlang so perhaps this is completely unnecessary. Perhaps there is a library that does this sort of thing?
Any advice is greatly appreciated. Thanks in advance!
I don't know if something exists already that does what you want, but you can easily implement it like this:
-module (match).
-compile([export_all]).
-define(MF(S), fun(S) -> true; (_)->false end).
match(F,V) -> F(V).
test() ->
Pattern = ?MF({ok,_}),
false = match(Pattern,{error,reason}),
true = match(Pattern,{ok,[1,2,3]}).
You might want to look at Erlang match specifications, which I believe are the sorts of patterns you're asking about. They're used for matching values in Erlang's tables and databases as well as in Erlang tracing. You might find some inspiration there.
I'm not sure I see your entire problem but it seems that a predicate function would suite you well. It's pretty common way to parameterize generic functions with them in a functional language. Take a look at lists functions such as map, foldl, filter.
I ended up using Elixir's macro functionality to implement something similar to Erlang's match specs. The code looks much cleaner(since I am simply defining functions with patterns) and they work very similar to Erlang's match specs.

Parse Math Expression in PHP

I'm currently trying to parse math expression into expression tree.
But I'm stuck on the stage where I need to implement functions and negates. I don't understand logic to do it using Shunting-Yard algorithm.
What I currently want to do is to support
Negates, like -(x+5)
Function calls, like min(x,y)
Power just after function name, like cos^2(x)
Implicit multiplication, like 2x is same as 2*x
Scientific notation
Constants e and pi
Can somebody tell me hints how to implement this?
An working, PSR-0 compatible implementation of the shunting yard algorithm can be found here: https://github.com/andig/php-shunting-yard/tree/dev.
It supports constants, custom functions etc.

A grammar for one variable functions in ANTLR

Hey!
I am looking for an ANTLR grammar for parsing one variable function expressions. It should support +,-, /, ^, special functions (e.g. cos, sin) and constants (pi, e) and parenthesis. I tried writing it myself but I get left-recursion warnings. Does anyone have a example that I can get started with?
I would like to write something like
x+sin(5x + pi^3)/(15e cos(x))
for example.
ANTLR grammars are preferred but other (E)BNF examples will be appreciated.
Eventually I would like to use it with AST output.
THANX
Ok, that was fast.
I found a great article on code project.
It has everything I wanted and more!

Resources