It seems that in Rascal a syntax declaration must come before a data declaration. Is that true? My experience is that if I put a syntax declaration after a data declaration, I got a parse error. Why is it a parse error?
Yes. Syntax declarations must come first in the file.
The reasoning is (I believe) that it should be simple to extract the grammar needed to parse the rest of the file.
You can of course always work around this if necessary by putting your type declarations in a separate file (probably only necessary if you need to add weirdo annotations to your grammar productions).
Related
How can I access the typed abstract syntaxe tree for all source files in a f# project in order as descibed in "analysing a whole project". So, what I need is the specific Microsoft.FSharp.Compiler.Tast of all files in a project.
Accessing the untyped syntax tree is quite simple, as described in walking an untyped ast. So, I expect there to be a corresponding interface to the tast.
The purpose is to transpile code from F# to another typed language, in this case scala, which need type annotations. A whole project should be translated at once.
The first URL you link shows how to get an FSharpAssemblySignature, but doesn't explain much of what to do with such a value. That type, and the immediate types it contains, FSharpEntity & FSharpMemberOrFunctionOrValue, are defined in Symbols.fs. The typed AST itself is defined in tast.fs. I don't know of any docs explaining the various types, except the comments in these two files.
I'm trying to write a Vapi file for MessagePack and am having a couple of issues, the first being that the resulting msgpack_object_print is incorrect because of the reference type of one of the parameters. The header file expects
void msgpack_object_print(FILE* out, msgpack_object o);
and my Vapi file contains
[CCode (instance_pos = 1.1)]
public void print (Posix.FILE out);
which generates the C output
msgpack_object_print (_tmp13_, &obj);
where obj is type msgpack_object *. This creates the error
examples/simple.c:173:34: error: incompatible type for argument 2 of ‘msgpack_object_print’
and it disappears if I remove the & from the generated C. So I'm wondering what my Vapi should contain to result in the correct output?
You can designated your msgpack_object class as [SimpleType] and it will be copied by value rather than by reference.
I have written a partial VAPI for MessagePack if you want to contribute back by using and testing it.
https://github.com/valum-framework/vala-extra-vapis/blob/msgpack/msgpack.vapi
Like already said, you need to use the [SimpleType] annotation on the class to have your type passed by value.
EDIT: Just adding that for bindings, it's a good thing to keep them in nemequ/vala-extra-vapis repository.
The terms "declaration" and "definition" are being used synonymously in Apple's Swift documentation and it's getting me confused.
Under the "Initialization" section (which talks about class initializers), Apple states:
You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition.
Further in a subsection they state:
You can set the initial value of a stored property from within an initializer, as shown above. Alternatively, specify a default property value as part of the property’s declaration.
I thought a variable declaration was different than a variable definition.
You are right that those two mean different thing, THOUGH I think most of the people just use both of them in the same meaning and I think that is also the case of those AppleDocs. Here is great article on subject:
Summary
A declaration provides basic attributes of a symbol: its type and its
name. A definition provides all of the details of that symbol--if it's
a function, what it does; if it's a class, what fields and methods it
has; if it's a variable, where that variable is stored. Often, the
compiler only needs to have a declaration for something in order to
compile a file into an object file, expecting that the linker can find
the definition from another file. If no source file ever defines a
symbol, but it is declared, you will get errors at link time
complaining about undefined symbols.
After doing much searching across the web for legitimate explanations, I have seemed to have found an answer:
The problem is that the two terms overlap to some extent. Definitions also serve as declarations, because they inject an identifier of a certain type to a scope. However, a declaration isn't a definition because it doesn't entail storage allocation for the declared object. To add to the confusion, the semantics of definitions and declarations is slightly different when applied to types and functions, as I will show momentarily. So let's look at a more detailed analysis of these two terms.
Here is the article: Declarations and Definitions.
The article gives further explanation and examples.
Declaration of variable mean to tell compiler their is a var\funct\struct of particular data type. Definition of variable mean asking compiler to allocate memory to variable or define storage for that variable. you can define a variable only one time but you can declare it as many time you want.
I think Apple's Swift 4 Language Reference can be construed as the authoritative answer. From the Declarations section (emphasis mine):
A declaration introduces a new name or construct into your program.
For example, you use declarations to introduce functions and methods,
variables and constants, and to define new, named enumeration,
structure, class, and protocol types. You can also use a declaration
to extend the behavior of an existing named type and to import symbols
into your program that are declared elsewhere.
In Swift, most declarations are also definitions in the sense that
they are implemented or initialized at the same time they are
declared. That said, because protocols don’t implement their members,
most protocol members are declarations only. For convenience and
because the distinction isn’t that important in Swift, the term
declaration covers both declarations and definitions.
clang builtin function "__builtin_NSStringMakeConstantString" returns const NSConstantString*,
that is not an Objective-C retainable object.
I want to replace this function with my own, but there seems to be no way to declare NSConstantString* as non-Objective-C pointer in Objective-C++ (you can do it in Objective-C by using struct NSConstnatString*). I am sure, that this function returns NSConstantString, because the following two lines output PK16NSConstantString:
printf("%s\n", typeid(__builtin___NSStringMakeConstantString("foo")).name());
printf("%s\n", typeid(const NSConstantString*).name());
Whenever I try to execute the following code I get error "Cannot initialize a variable of type 'const NSConstantString *' with an rvalue of type 'const NSConstantString *'":
const NSConstantString* a = __builtin___NSStringMakeConstantString("foo");
Everything works OK if I add bridge cast, so this means that NSConstantString* is returned as "raw" Objective-C pointer, but I have to create a function that returns exactly the same result as "__builtin_NSStringMakeConstantString", so I have no option to use __bridge.
Whenever I try to return const NSConstantString* from a function, it is always returned as an Objective-C retainable pointer and there seems to be no way to declare it as C pointer except this:
typedef typeof __builtin___NSStringMakeConstantString("") rawNSConstnatStringPtr;
So the question is: Is there a way to declare a nonretainable pointer to NSConstantString* (without using typeof)?
You think _builtin__NSStringMakeConstant returns NSConstantString, because the compiler is tricking you.
I suggest you check out the clang source code: http://llvm.org/docs/GettingStarted.html#git-mirror
Then search the source code: git grep __builtin___NSStringMakeConstantString. You find that it's defined in include/clang/Basic/Builtins.def like this:
BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
The second argument is the function signature, and the comment at the top of the file explains what it means. The FC* part is the return type, and means “constant CFString const pointer”. That makes sense since CFString and NSString are toll-free bridged.
But it doesn't make sense because the error message specifically mentions NSConstantString. So git grep -w NSConstantString to see where that's coming from. You eventually find method ASTContext::getCFConstantStringType in lib/ast/ASTContext.cpp. This method creates a struct type declaration with the identifier NSConstantString, but it never adds the declaration to any scope (it doesn't call PushOnScopeChains or AddDecl). So the NSConstantString identifier can appear in diagnostics, but you cannot access the type by name in your source code. The NSConstantString type declared in NSString.h is, as far as the compiler is concerned, unrelated to this synthesized type.
Anyway, the important question is why you want to override __builtin___NSStringMakeConstantString, which you did not say. If it's because you want to use your own constant string class, you're going about it the wrong way.
I don't think you can override that function, because it is built in to the compiler. You would need to modify the compiler source code if you want to change its meaning.
Also, I don't think the compiler actually uses that function to create Objective-C string literals. Running git grep __builtin___NSStringMakeConstantString doesn't turn up any places where the compiler generates a call to it. The compiler handles #"string" syntax in lib/Parse/ParseObjc.cpp and lib/Sema/SemaExprObjC.cpp (look for methods named ParseObjCStringLiteral in both files). The compiler looks up the NSConstantString type by name (which means it should get the one from the NSString.h header file) and creates an instance of ObjCStringLiteral with that type.
You should be able to make it look up a different class for the constant string type (instead of NSConstantString) using the -fconstant-string-class command-line flag, but I don't know how well that works. This question implies that it might not work. Even if it does work, I think you're constrained to using the same memory layout as NSConstantString, in which case, why bother using a different class?
import is a keword, yet the following works fine:
import 'dart:io';
void main() {
import() {
print("Imported");
}
import();
}
Is this supposed to work?
Is the language sufficiently stable that using this will continue to work?
What is special about import versus say class, which does not work and what other keywords/may be are fair game?
Yes, this is supposed to work. And I think that yes, you can be reasonably sure that this will continue to work. To explain, let's take a look at the language specification.
Section 16.1.1 (Reserved words) explains that a reserved word may not be used as an identifier; it is a compile-time error if a reserved word is used where an identifier is expected. Here is the list of reserved words: assert, break, case, catch, class, const, continue, default, do, else,
enum, extends, false, final, finally, for, if, in, is, new, null, rethrow, return, super, switch, this, throw, true, try, var, void, while, with. Note that import isn't mentioned here.
Then, sections 12.30 (Identifier Reference) explains that there is a set of built-in identifiers which looks like this: abstract, as, dynamic, export, external, factory, get, implements, import, library, operator, part, set, static, typedef. And it is a compile-time error if a built-in identifier is
used as the declared name of a class, type parameter or type alias. Note that import falls into this group -- so you can't use it as a type, but you can use it elsewhere (like in your case, as a function name).
And a non-normative part of the section 12.30 explains the difference: Built-in identifiers are identifiers that are used as keywords in Dart, but are not reserved words in Javascript.
Just to note, in this answer, I quoted the PDF form of the Dart Language Specification version 0.30.