Synopsis Compute use-def information for the variables in a Pico program.
Examples The definitions of a variable are the source code locations where a variable gets a value. The uses of a variable are the location where the value of that variable is used. Both concepts are relevant for program analysis and are defined here.
module demo::lang::Pico::UseDef

import Prelude;
import demo::lang::Pico::Abstract;
import demo::lang::Pico::ControlFlow;

set[Occurrence] usesExp(EXP e, STATEMENT s) = 
  u:id(PicoId Id) := e ? {< u@location, Id, s>}
                       : {< u@location, Id, s> | /u:id(PicoId Id) <- e };
set[Occurrence] usesStat(s:asgStat(PicoId Id, EXP e)) = usesExp(e, s);

set[Occurrence] usesStat(s: ifElseStat(EXP e,
                              list[STATEMENT] s1,
                              list[STATEMENT] s2)) =
   usesExp(e, s) + usesStats(s1) + usesStats(s2);

set[Occurrence] usesStat(s: whileStat(EXP e,
                              list[STATEMENT] s1)) =
   usesExp(e, s) + usesStats(s1);

set[Occurrence] usesStats(list[STATEMENT] stats) =  
   {*usesStat(s) | s <- stats};

public set[Occurrence] uses(PROGRAM p) = usesStats(p.stats);

public set[Occurrence] defs(PROGRAM p) =                 
   { < stat@location, v, stat > | /stat:asgStat(PicoId v, EXP e) <- p.stats};
Recall that Occurrence was introduced in Pico/Abstract; it is a parameterized container to associate program entities with their location.

The function uses () has a Pico program as argument and returns a set of occurrences (uses) of Pico identifiers:
  • First, the local variable r is declared; it will contain the set of occurrences.
  • Next, all statements in the program (P.stats) are visited () using a Rascal:Expressions/Visit statement.
  • There is one case of interest, the occurrence of an identifier in an expression (). Note that we use a labeled pattern u:id(PicoId Id) , so that we can access the whole expression that was matched and retrieve its location information (u@location) when we are adding a pair to the set of occurrences.
  • When the whole program has been visited, we return r ().
The function defs () has a Pico program as argument and returns a set of occurrences (definitions) of Pico identifiers. The definition consists of a single set comprehension that consists of the following parts:
  • ... <- P. stats enumerates all statements in the program.
  • /asgStat(PicoId Id, EXP Exp) <- P.stats uses a descendant (deep) match (/, see Rascal:Descendant) to find all assignment statements.
  • For each assignment statement a (location, identifier) pair is added to the result.
Is this page unclear, or have you spotted an error? Please add a comment below and help us to improve it. For all other questions and remarks, visit