Replacement error calculating replacement in clang - clang

I'm trying to refactor if-else branches and am unable to generate accurate Replacements for it. I try to fetch nodes using:
clang::IfStmt *ifstmt = const_cast<clang::IfStmt *>(
result.Nodes.getNodeAs<clang::IfStmt>("if_simple_else_bind_name"))
and then calculate its source range using
ifstmt->getSourceRange()
However, I find that after using this SourceRange for calculating the start and end for the branch sometimes misses a semicolon for cases like these:
if(cond) {
return a;
}
else
return b; <-- here
How do I find the correct source range and further on generate the correct replacement rewriting the whole branch regardless of whether there are any braces or simple statements?
Any help would be highly appreciated!

Related

Clean way to loop over a masked list in Julia

In Julia, I have a list of neighbors of a location stored in all_neighbors[loc]. This allows me to quickly loop over these neighbors conveniently with the syntax for neighbor in all_neighbors[loc]. This leads to readable code such as the following:
active_neighbors = 0
for neighbor in all_neighbors[loc]
if cube[neighbor] == ACTIVE
active_neighbors += 1
end
end
Astute readers will see that this is nothing more than a reduction. Because I'm just counting active neighbors, I figured I could do this in a one-liner using the count function. However,
# This does not work
active_neighbors = count(x->x==ACTIVE, cube[all_neighbors[loc]])
does not work because the all_neighbors mask doesn't get interpreted correctly as simply a mask over the cube array. Does anyone know the cleanest way to write this reduction? An alternative solution I came up with is:
active_neighbors = count(x->x==ACTIVE, [cube[all_neighbors[loc][k]] for k = 1:length(all_neighbors[loc])])
but I really don't like this because it's even less readable than what I started with. Thanks for any advice!
This should work:
count(x -> cube[x] == ACTIVE, all_neighbors[loc])

`knitr_out, `file_out` and `vis_drake_graph` usage in R:drake

I'm trying to understand how to use knitr_out, file_out and vis_drake_graph properly in drake.
I have two questions.
Q1: Usage of knitr_out and file_out to create markdown reports
While a code like this works correctly for one of my smaller projects:
make_hyp_data_aggregated_report <- function() {
render(
input = knitr_in("rmd/hyptest-is-data-being-aggregated.Rmd"),
output_file = file_out("~/projectname/reports/01-hyp-test.html"),
quiet = TRUE
)
}
plan <- drake_plan(
...
...
hyp_data_aggregated_report = make_hyp_data_aggregated_report()
...
...
)
Exactly similar code in my large project (with ~10+ reports) doesn't work exactly right. i.e., while the reports get built, the knitr_in objects don't get displayed as the blue squares in the graph using drake::vis_drake_graph() in my large project.
Both projects use the drake::loadd(....) within the markdown to get the objects from cache.
Is there some code in vis_drake_graph that removes these squares once the graph gets busy?
Q2: file_out objects in vis_drake_graph
Is there a way to display the file_out objects themselves as circles/squares in vis_drake_graph?
Q3: packages showing up in vis_drake_graph
Is there a way to avoid vis_drake_graph from printing the packages explicitly? (Basically anything with the ::)
Q1
Every literal file path needs its own knitr_in() or file_out(). If you have one function with one knitr_in(), even if you use the function multiple times, that still only counts as one file path. I recommend writing these keywords at the plan level, e.g.
plan <- drake_plan(
r1 = render(knitr_in("report1.Rmd"), output_file = file_out("report1.html")),
r2 = render(knitr_in("report2.Rmd"), output_file = file_out("report2.html")),
r3 = render(knitr_in("report3.Rmd"), output_file = file_out("report3.html"))
)
Q2
They should appear unless you set show_output_files = FALSE in vis_drake_graph().
Q3
No, but if it's any consolation, I do regret the decision to track namespaced functions and objects at all in drake. drake's approach is fundamentally suboptimal for tracking packages, and I plan to get rid of it if there ever comes time for a round of breaking changes. Otherwise, there is no way to get rid of it except vis_drake_graph(targets_only = TRUE), which also gets rid of all the imports in the graph.

How does the data structure for a lexical analysis look?

I know the lexical analyser tokenizes the input and stores it in a stream, or at least that is what I understood. Unfortunately nearly all articles I have read only talk about lexing simple expressions. What I am interested in is how to tokenize something like:
if (fooBar > 5) {
for (var i = 0; i < alot.length; i++) {
fooBar += 2 + i;
}
}
Please note that this is pseudo code.
Question: I would like to know how the data structure looks like for tokens created by the lexer? I really have no idea for the example i gave above where code is nested. Some example would be nice.
First of all, tokens are not necessarily stored. Some compilers do store the tokens in a table or other data structure, but for a simple compiler (if there is such a thing) it's sufficient in most cases that the lexer can return the type of the next token to be parsed and then in some cases the parser might ask the lexer for the actual text that the token is made up of.
If we use your sample code,
if (fooBar > 5) {
for (var i = 0; i < alot.length; i++) {
fooBar += 2 + i;
}
}
The type of the first token in this sample might be defined as TOK_IF corresponding to the "if" keyword. The next token might be TOK_LPAREN, then TOK_IDENT, then TOK_GREATER, then TOK_INT_LITERAL, and so on. What exactly the types should be is defined by you as the author of the lexer (or tokenizer) code. (Note that there are about a million different tools to help you avoid the somewhat tedious task of coming up with these details by hand.)
Except for TOK_IDENT and TOK_INT_LITERAL the tokens we've seen so far are defined entirely by their type. For these two, we would need to be able to ask the lexer for the underlying text so that we can evaluate the value of the token.
So a tiny excerpt of the parser dealing with an IF statement in pseudo-code might look something like:
...
switch(lexer.GetNextTokenType())
case TOK_IF:
{
// "if" statement
if (lexer.GetNextTokenType() != TOK_LPAREN)
throw SyntaxError('( expected');
ParseRelationalExpression(lexer);
if (lexer.GetNextTokenType() != TOK_RPAREN)
throw SyntaxError(') expected');
...
and so on.
If the compiler did choose to actually store the tokens for later reference, and some compilers do e.g. to allow for more efficient backtracking, one way would be to use a structure similar to the following
struct {
int TokenType;
char* TokenStart;
int TokenLength;
}
The container for these might be a linked list or std::vector (assuming C++).

How to get a location of a number value?

Suppose I want to print all locations with a hard coded value, in a context were d is an M3 Declaration:
top-down visit(d) {
case \number(str numberValue) :
println("hardcode value <numberValue> encountered at <d#\src>");
}
The problem is that the location <d#\src> is too generic, it yields the entire declaration (like the whole procedure). The expression <numberValue#\src> seems more appropriate, but it is not allowed, probably because we are too low in the parse tree.
So, the question is how to get a parent E (the closest parent, like the expression itself) of <numberValue> such that <E#\src> is defined?
One option is to add an extra level in the top-down traversal:
top-down visit(d) {
case \expressionStatement(Expression stmt): {
case \number(str numberValue) :
println("hardcode value <numberValue> encountered at <stmt#\src>");
}
}
This works, but has some drawbacks:
It is ugly, in order to cover all cases we have to add many more variants;
It is very inefficient.
So, what is the proper way to get the location of a numberValue (and similar low-level constructs like stringValue's, etc)?
You should be able to do the following:
top-down visit(d) {
case n:\number(str numberValue) :
println("hardcode value <numberValue> encountered at <n#\src>");
}
Saying n:\number(str numberValue) will bind the name n to the \number node that the case matched. You can then use this in your message to get the location for n. Just make sure that n isn't already in scope. You should be able to create similar patterns for the other scenarios you mentioned as well.

Attempt to perform arithmetic on table value

I'm maintaining someone else's Lua code, and Lua is not my preferred language. This is probably a complete noob question, but I can't seem to find the answer on Google or SO...
The following code
if !(v.LastHealth == v:Health()) then
local newColor = {}
newColor.r = v.orgColor.r - (v.orgColor.r - curColor.r) --This is the line the error occurs on
newColor.g = v.orgColor.g - (v.orgColor.g * clrPercent)
newColor.b = v.orgColor.b - (v.orgColor.b * clrPercent)
newColor.a = v.orgColor.a - (v.orgColor.a - curColor.a)
v:SetColor( newColor )
produces the error
attempt to perform arithmetic on field 'r' (a table value)
orgColor (maybe, not totally certain- v.orgColor may be an outdated thing) and curColor are tables that have entries (Uh. I think. bla.x is the same as bla[x] in Lua, right?) r, g, b, and a. Apparently I can't do math on things that come from tables? Should I stow all these values in local variables before working with them? That doesn't seem right.
EDIT:
Printing v.orgColor gives table: 0x40390080, which I assume means it exists and is a table. What's odd is, v.orgColor.r gives another table! That sounds like the cause.
As it turns out, v.orgColor was not, as I had presumed, set by the host program, but was set by the same script as the code sample is from. There was an API change that made a function that used to return four RGBA values instead return a table of those same values; the old code set orgColor.r to the table containing those values, causing the error.
Moral of the story, I suppose, is that you should always make sure you know what's setting the variables you're working with.

Resources