I know Rascal is intended to be a meta-language for other languages. Do these languages include Rascal itself? Is there any meta-facilities like quote a la Lisp available or planned?
You can transform Rascal using Rascal by including the Rascal syntax definition and simply using the normal quotes. We are not planning to add quoting at run-time for Rascal itself afaik.
One thing that I forgot to mention earlier, is that the "resources" mechanism can be used to manipulate Rascal code at "import" time. You can write any function as in:
#resource{myScheme}
str generateNewCode(str name, loc l) = ...
generateNewCode should generate a Rascal module with name name.
After this you can import as follows:
import MyModule = myScheme://someOtherModuleName;
And then the module that is generated by generateNewCode is imported by Rascal in the module that you typed the import in.
Nothing stops you from writing a generateNewCode function that parses another module, rewrites or extends it and then will be imported.
Related
I am building a Xtext DSL and I want to embed Xbase expressions in some specific places to interpret part of my models using the Xbase interpreter, but I am not able to have method completion in the generated editor.
I reused the examples provided here: https://www.eclipse.org/Xtext/documentation/201_sevenlang_introduction.html, and manage to integrate Xbase as part of my grammar. Keyword completion proposal is working fine (i.e. do, for, while ...), but I can't find a way to have completion for Java/Xbase methods (e.g. newArrayList, or myArray.add(X)).
Clarification from comments below: if I write var x = newArrayList in the editor the method is not styled in italic but I don't have any error either.
This is a sample version of the grammar I am using:
grammar org.xtext.example.common2.Common2 with org.eclipse.xtext.xbase.Xbase
generate common2 "http://www.xtext.org/example/common2/Common2"
import "http://www.eclipse.org/xtext/xbase/Xbase"
Test returns Test:
{Test}
'test'
expressions+=Script
;
Script returns XBlockExpression:
{Script}
'{'
(expressions+=XExpressionOrVarDeclaration ';'?)*
'}'
;
I found out that if I change my grammar to the following one I can have the completion as expected:
grammar org.xtext.example.common2.Common2 with org.eclipse.xtext.xbase.Xbase
generate common2 "http://www.xtext.org/example/common2/Common2"
import "http://www.eclipse.org/xtext/xbase/Xbase"
Test returns XBlockExpression:
{Test}
'test'
expressions+=Script
;
Script returns XBlockExpression:
{Script}
'{'
(expressions+=XExpressionOrVarDeclaration ';'?)*
'}'
;
My guess is that all the tree must be composed of instances of XExpression to enable the completion, but I don't understand why? To me Test should not be a subclass of XBlockExpression (in my real-world use case Test has additional attributes/references), but it should contain an XBlockExpression.
Is there a way to achieve this? Any help/resource to look at would be much appreciated
Note
I already checked this SO question How to embed XBase expressions in an Xtext DSL, I already have xbase.lib in my build path.
I'm going through the EUnit chapter in Learn You Some Erlang and one thing I am noticing from all the code samples is the test functions are never declared in -export() clauses.
Why is EUnit able to pick these test functions up?
From the documentation:
The simplest way to use EUnit in an Erlang module is to add the following line at the beginning of the module (after the -module declaration, but before any function definitions):
-include_lib("eunit/include/eunit.hrl").
This will have the following effect:
Creates an exported function test() (unless testing is turned off, and the module does not already contain a test() function), that can be used to run all the unit tests defined in the module
Causes all functions whose names match ..._test() or ..._test_() to be automatically exported from the module (unless testing is turned off, or the EUNIT_NOAUTO macro is defined)
Glad I found this question because it gives me a meaningful way to procrastinate and I was wondering how functions get created and exported dynamically.
Started by looking at the latest commit affecting EUnit in the Erlang/OTP Github repo, which is 4273cbd. (The only reason for this was to find a relatively stable anchor instead of git branches.)
0. Include EUnit's header file
According EUnit's User's Guide, the first step is to -include_lib("eunit/include/eunit.hrl"). in the tested module, so I assume this is where the magic happens.
1. otp/lib/eunit/include/eunit.hrl (lines 79 - 91)
%% Parse transforms for automatic exporting/stripping of test functions.
%% (Note that although automatic stripping is convenient, it will make
%% the code dependent on this header file and the eunit_striptests
%% module for compilation, even when testing is switched off! Using
%% -ifdef(EUNIT) around all test code makes the program more portable.)
-ifndef(EUNIT_NOAUTO).
-ifndef(NOTEST).
-compile({parse_transform, eunit_autoexport}).
-else.
-compile({parse_transform, eunit_striptests}).
-endif.
-endif.
1.1 What does -compile({parse_transform, eunit_autoexport}). mean?
From the Erlang Reference Manual's Module chapter (Pre-Defined Module Attributes):
-compile(Options).
Compiler options. Options is a single option or a list of options. This attribute is added to the option list when
compiling the module. See the compile(3) manual page in Compiler.
On to compile(3):
{parse_transform,Module}
Causes the parse transformation function
Module:parse_transform/2 to be applied to the parsed code before the
code is checked for errors.
From the erl_id_trans module:
This module performs an identity parse transformation of Erlang code.
It is included as an example for users who wants to write their own
parse transformers. If option {parse_transform,Module} is passed to
the compiler, a user-written function parse_transform/2 is called by
the compiler before the code is checked for errors.
Basically, if module M includes the {parse_transform, Module} compile option, then all of M's functions and attributes can be iterated through using your implementation of Module:parse_transform/2. Its first argument is Forms, which is M's module declaration described in Erlang's abstract format (described in Erlang Run-Time System Application (ERTS) User's Guide.
2. otp/lib/eunit/src/eunit_autoexport.erl
This module only exports parse_transfrom/2 to satisfy {parse_transform, Module} compile option and its first order of business is to figure out what are the configured suffixes for test case functions and generators. If not set manually, using _test and _test_ respectively (via lib/eunit/src/eunit_internal.hrl).
It then scans all the functions and attributes of your module using eunit_autoexport:form/5, and builds a list of to be exported functions where the suffixes above match (plus the original functions. I may be wrong on this one...).
Finally, eunit_autoexport:rewrite/2 builds a module declaration from the original Forms (given to eunit_autoexport:parse_transform/2 as the first argument) and the list of functions to be exported (that was supplied by form/5 above). On line 82 it injects the test/0 function mentioned in the EUnit documentation.
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.
I'm using xbase
grammar xolang.Xolang with org.eclipse.xtext.xbase.Xbase
and an
XBlockExpression
where I expect to write my code
When write an expression like
val c = 1 + 1
Then I get the following error
The method +(int) is undefined
The same happens with Strings. In fact it happens with every binary operator: ==, < , >, ... Now I know that xbase supports operator overloading, maybe that has something to do with it? (Maybe I still have to define somewhere that you can add numbers?)
I solved my problem.
You need to add the xbase.lib jarfile (the right version of course) to the buildpath of the project that uses your DSL.
If you wonder how you can easily add the xbase lib in Eclipse: Right Click on your Project that makes use of your DSL, select Build-Path->Add Libraries and choose XTend Library. The XTend Library includes the correct XBase Lib.
I'm developing a xtext-based language which should refer to objects defined in a vendor-specific file format.
E.g. this file format defines messages, my language shall define Rules that work with these messages. Of course i want to use xtext features e.g. to autocomplete/validate message names, attributes etc.
Not sure if that is a good idea, but I came up with the following:
Use one xtext project to describe the file format
Add a dependency for this project to my DSL project, import the file format grammar to my grammar
import the description files via importURI
FileFormat grammar:
grammar com.example.xtext.fileformat.FileFormat;
generate fileformat "http://xtext.example.com/fileformat/FileFormat"
[...]
DSL grammar:
grammar com.example.xtext.dsl.DSL;
import "http://xtext.example.com/fileformat/FileFormat" AS ff;
Model:
rules += Rule*;
Rule: ImportFileRule | SampleRule;
ImportFileRule: "IMPORT" importURI=STRING "AS" name=ID ";";
SampleRule: "FORWARD" msg=[ff::Message] ";"
First of all: This works fine.
Now, different imported files may define messages with colliding names,
and I want to use fully qualified names for messages anyways.
The prefix for the message names should be defined in my DSL, e.g. the name of the ImportFileRule.
So I would like to use something like:
IMPORT "first-incredibly-long-filename-with-version-and-stuff.ff" AS first;
IMPORT "second-incredibly-long-filename-with-version-and-stuff.ff" AS second;
FORWARD first.msg_1; // references to msg_1 in first file
FORWARD second.msg_1; // references to msg_1 in second file
Unfortunately I don't see a easy way to achieve this with xtext.
At the moment I'm using a ID for the namespace qualifier and custom ProposalProvider/Validator classes,
which is ugly in detail and bypasses the EMF index, becoming slow with files of 1000 messages and 50000 attributes...
Would there be a right way to do it?
Was it a good idea to use xtext to parse the definition files in the first place?
I have two ideas what to check.
Xtext has a specific global scope provider called ImportedNameSpaceAwareScopeProvider. By using an overridden version of this, you could specify other headers to consider.
Check the implementation of the xtext grammar itself, as it supports such a feature with EPackage imports. I am not exactly sure, how it operates, but should work this way.
Finally, I ended up using the SimpleNamesFragment, ImportURIScopingFragment and a custom ScopeProvider derived from AbstractDeclarativeScopeProvider.
That way, I had to implement ScopeProvider methods for quiet a few rules but was much more flexible in using my "namespace prefix".
E.g. it is simple to implement syntaxes like
FORWARD FROM first: msg_01, msg_02;