Agda: How to check the type even when file doesn't typecheck yet? - agda

In agda-mode there is C-c C-d command to infer a type of expression. This is especially needed when we arrive at a type error! But exactly then this command doesn't work. I would guess that this is because the feature wants to evaluate the expression type in the context of the working file. Rightfully so - but is there a way to bypass it and for example find the expression type in the context of the longest typechecking prefix of a file?
I'm using agda-mode for vs-code but emacs tips are appreciated as well as they hopefully translate.
Also did I miss some feature to infer the type of expression at cursor? The way I use C-c C-d (infer type) is after this command I input the expression of interest manually (or paste it). Would be nice to get a type of the word the cursor points to.

Related

Dialyzer warns about no_exit on bad record construction - is this a bug?

When Dialyzer encounters a record literal where a required field is not initialized, it thinks control flow stops at the line with the record literal.
Example:
-module(sample).
-export([foo/0]).
-record(boo, {a :: number()}).
foo() ->
erlang:display(#boo{}).
Errors:
13> dialyzer:run([{files, ["/Users/mheiber/sample.erl"]}, {from, src_code}]).
[{warn_return_no_exit,
{"/Users/mheiber/sample.erl",11},
{no_return,[only_normal,foo,0]}},
{warn_matching,
{"/Users/mheiber/sample.erl",12},
{record_constr,
["#boo{a::'undefined'}","a::number()"]}}]
Is this a bug? The runtime semantics of Erlang do not match how Dialyzer is modeling them: ERTS (for better or worse!) chugs along, happily assigning the atom 'undefined' to to any unitialized fields.
Clarification: what I mean here is that it's preferable, where feasible, for the static checking to reflect how Erlang works at run time.
So is this a Dialyzer bug?
The way Dialyzer handles these incorrectly-initialized records is pernicious, because it can trigger a cascade of spurious warnings–when Dialyzer thinks a line of function foo is unreachable, any functions that are reachable only from foo are also considered dead.
No, it's not a bug.
I'd say that it's a limitation caused by the fact that Erlang is dynamically typed and that the -type directives are not used in runtime.
Dialyzer is built on top of ERTS, not the other way around.
The problem in this case is that dialyzer does not know how to continue its execution: Should it use the type defined in the record definition or the actual record initialization? It reports an error and the actual fix is left to the programmer.

Evaluate already parsed duration expression

I'm writing a tool which reads go code and parses some duration expressions like: dur := 5 * time.Minute. I already have the parsing step done and got a *ast.BinaryExpr. How can I evaluate this expression and get its value?
Is there something in the toolchain/packages or do I need to go by hand?
I think parser package is the one your looking for.
go also has a package named eval (https://godoc.org/github.com/apaxa-go/eval) that evaluates expressions.
And there are two libraries that might help you down the line.
https://github.com/PaesslerAG/gval
https://github.com/Knetic/govaluate
Gval (Go eVALuate) provides support for evaluating arbitrary expressions, in particular Go-like expressions.
Good luck!

Find clang::Type in Clang AST by name

In Clang AST, is it possible to find type by name?
For example I have qualified name : nspace::my_type<int, 10u>. How can I check if type is present in current translation unit?
NOTE: my knowledge is extremely limited from just once writing a clang tidy check to do some update I needed. Might be wrong.
There are two possible things that you might need in clang AST depending on the task at hand: Type and TypeLocation. I needed the type location, so this is what I'll mention first.
Find the type spelling.
In this case what you actually want is the TypeLocation ast nodes. They represent a spelling of a type.
Unfortunately are not printed by clang-query.
The way to search for them is by using a type_loc matcher.
This is from something I needed: find all specialisations of a wide template.
This would find me all the spellings of wide<T>
l isWide hasDeclaration(classTemplateDecl(namedDecl(hasName("wide"))))
l isWideSpec templateSpecializationType(isWide)
l wideLoc typeLoc(loc(isWideSpec))
wideLoc - is what I was using to change the spelling of the type.
Different type_loc have parents that are also type_loc.
So for example I can find all entries of T unless they are inside wide<T>
typeLoc(loc(asString("T")), unless(hasAncestor(wideLoc)))
Find all of the actual usages of the type, regardless of how it is spelled.
Now for this type of problem you'd need to match on a type.
Have never done this myself, but we can see abseil doing this for example here:
https://github.com/llvm/llvm-project/blob/b426b45d101740a21610205ec80610c6d0969966/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp#L36
PS. Just in case - all clang ast matchers:
https://clang.llvm.org/docs/LibASTMatchersReference.html

Is possible to use F# pattern matching as a solver/library for another language or DSL?

I'm building a toy language, I want to have pattern matching. I could build the whole thing itself (and don't know how) but because I will do it in F# I wonder if I can defer the whole thing to it.
So, I have a interpreter and my custom syntax. If I give a AST, is possible to use F# use it to solve the pattern matching?
Another way to look at this, is possible to use F# pattern matching from C# and other .NET languages?
For example, if the program is (in invented syntax almost like F#):
case x with
( 1 , 2 , Three):
print("Found 1, 2, or 3!")
else var1:
print("%d" % var1)
Is possible to do
matched, error = F#MagicHere.Match(EvaluateMyAST)
I'm not exactly sure if I understand your question correctly, but I suspect you could use F# Compiler Service to do what you need. Basically, the compiler service lets you call some of the tasks that the compiler performs (and it is a normal .NET library).
The first step would be to turn your AST into valid F# code - I guess you could find a systematic way of doing this (but it requires some thinking). Then you can use F.C.S to:
Type-check the expression, which gives you warnings for overlapping cases and missing cases (e.g. when you have an incomplete pattern match).
It gives you the AST of the pattern matching and I believe you can even get a decision tree that you can interpret to evaluate the pattern matching.
Alternatively, you could use F.C.S to compile the code and run it (provided that you can translate your DSL to F# code)

Compiler Design : Is "variable not declared" a syntactic error or semantic error?

Is such type of an error produced during type checking or when input is being parsed?
Under what type should the error be addressed?
The way I see it it is a semantic error, because your language parses just fine even though your are using an identifier which you haven't previously bound--i.e. syntactic analysis only checks the program for well-formed-ness. Semantic analysis actually checks that your program has a valid meaning--e.g. bindings, scoping or typing. As #pst said you can do scope checking during parsing, but this is an implementation detail. AFAIK old compilers used to do this to save some time and space, but I think today such an approach is questionable if you don't have some hard performance/memory constraints.
The program conforms to the language grammar, so it is syntactically correct. A language grammar doesn't contain any statements like 'the identifier must be declared', and indeed doesn't have any way of doing so. An attempt to build a two-level grammar along these lines failed spectacularly in the Algol-68 project, and it has not been attempted since to my knowledge.
The meaning, if any, of each is a semantic issue. Frank deRemer called issues like this 'static semantics'.
In my opinion, this is not strictly a syntax error - nor a semantic one. If I were to implement this for a statically typed, compiled language (like C or C++), then I would not put the check into the parser (because the parser is practically incapable of checking for this mistake), rather into the code generator (the part of the compiler that walks the abstract syntax tree and turns it into assembly code). So in my opinion, it lies between syntax and semantic errors: it's a syntax-related error that can only be checked by performing semantic analysis on the code.
If we consider a primitive scripting language however, where the AST is directly executed (without compilation to bytecode and without JIT), then it's the evaluator/executor function itself that walks the AST and finds the undeclared variable - in this case, it will be a runtime error. The difference lies between the "AST_walk()" routine being in different parts of the program lifecycle (compilation time and runtime), should the language be a scripting or a compiled one.
In the case of languages -- and there are many -- which require identifiers to be declared, a program with undeclared identifiers is ill-formed and thus a missing declaration is clearly a syntax error.
The usual way to deal with this is to incorporate information about symbols in a symbol table, so that the parse can use this information.
Here are a few examples of how identifier type affects parsing:
C / C++
A classic case:
(a)-b;
Depending on a, that's either a cast or a subtraction:
#include <stdio.h>
#if TYPEDEF
typedef double a;
#else
double a = 3.0;
#endif
int main() {
int b = 3;
printf("%g\n", (a)-b);
return 0;
}
Consequently, if a hadn't been declared at all, the compiler must reject the program as syntactically ill-formed (and that is precisely the word the standard uses.)
XML
This one is simple:
<block>Hello, world</blob>
That's ill-formed XML, but it cannot be detected with a CFG. (Nonetheless, all XML parsers will correctly reject it as ill-formed.) In the case of HTML/SGML, where end-tags may be omitted under some well-defined circumstances, parsing is trickier but nonetheless deterministic; again, the precise declaration of a tag will determine the parse of a valid input, and it's easy to come up with inputs which parse differently depending on declaration.
English
OK, not a programming language. I have lots of other programming language examples, but I thought this one might trigger some other intuitions.
Consider the two grammatically correct sentences:
The sheep is in the meadow.
The sheep are in the meadow.
Now, what about:
The cow is in the meadow.
(*) The cow are in the meadow.
The second sentence is intelligible, albeit ambiguous (is the noun or the verb wrong?) but it is certainly not grammatically correct. But in order to know that (and other similar examples), we have to know that sheep has an unmarked plural. Indeed, many animals have unmarked plurals, so I recognize all the following as grammatical:
The caribou are in the meadow.
The antelope are in the meadow.
The buffalo are in the meadow.
But definitely not:
(*) The mouse are in the meadow.
(*) The bird are in the meadow.
etc.
It seems that there is a common misconception that because the syntactic analyzer uses a context free grammar parser, that syntactic analysis is restricted to parsing a context free grammar. This is simply not true.
In the case of C (and family), the syntax analyzer uses a symbol table to help it parse. In the case of XML, it uses the tag stack, and in the case of generalize SGML (including HTML) it also uses tag declarations. Consequently, the syntax analyzer considered as a whole is more powerful than the CFG, which is just a part of the analysis.
The fact that a given program passes the syntax analysis does not mean that it is semantically correct. For example, the syntax analyser needs to know whether a is a type or not in order to correctly parse (a)-b, but it does not need to know whether the cast is in fact possible, in the case that it a is a type, or that a and b can meaningfully be subtracted, in the case that a is a variable. These verifications can happen during type analysis after the parse tree is built, but they are still compile-time errors.

Resources