Navigation
Synopsis Parse Func program from string or file and convert to an abstract syntax tree.
Description To simplify later processing, Func programs are converted to an abstract syntax tree.
Examples The concrete syntax for Func is described in Func/ConcreteSyntax and its abstract syntax in Func/AbstractSyntax. Rather than manually writing conversion rules from Func parse trees to Func abstract syntax trees we use our secret weapon: Rascal:implode that performs the mapping for us. As you see when you compare the concrete and abstract syntax, the ground work has already been done by appropriately labelling concrete rules with constructor names of the abstract syntax.

Here is the code for the load funcion:
module demo::lang::Func::Load

import demo::lang::Func::Func;
import demo::lang::Func::AST;
import demo::lang::Func::Parse;

import ParseTree;

public demo::lang::Func::AST::Prog implode(demo::lang::Func::Func::Prog p) = 
       implode(#demo::lang::Func::AST::Prog, p);

public demo::lang::Func::AST::Prog load(loc l) = implode(parse(l));
public demo::lang::Func::AST::Prog load(str s) = implode(parse(s));

This looks simple but also slightly intimidating due to the many qualified names. The issue is that the names in the concrete and abstract syntax are (on purpose) overloaded. A name like Prog can be the one from the concrete syntax(i.e., demo::lang::Func::Func::Prog) or the one from the abstract syntax (i.e., demo::lang::Func::AST::Prog).

For instance, the local version of implode defined here get a concrete Prog as argument and returns an abstract one. Both load function return an abstract Prog.

Let's try this on example F0:
fact(n) = if n <= 1 then
             1 
          else 
             n * fact(n-1)
          end
rascal>import demo::lang::Func::Load;
ok
rascal>import demo::lang::Func::programs::F0;
ok
rascal>load(F0);
Prog: prog([func(
      "fact",
      ["n"],
      cond(
        leq(
          var("n")[
            @location=|file://-|(13,1,<1,13>,<1,14>),
            @comments=()
          ],
          nat(1)[
            @location=|file://-|(18,1,<1,18>,<1,19>),
            @comments=()
          ])[
          @location=|file://-|(13,6,<1,13>,<1,19>),
          @comments=()
        ],
        nat(1)[
          @location=|file://-|(38,1,<2,13>,<2,14>),
          @comments=()
        ],
        mul(
          var("n")[
            @location=|file://-|(70,1,<4,13>,<4,14>),
            @comments=()
          ],
          call(
            "fact",
            [sub(
                var("n")[
                  @location=|file://-|(79,1,<4,22>,<4,23>),
                  @comments=()
                ],
                nat(1)[
                  @location=|file://-|(81,1,<4,24>,<4,25>),
                  @comments=()
                ])[
                @location=|file://-|(79,3,<4,22>,<4,25>),
                @comments=()
              ]])[
            @location=|file://-|(74,9,<4,17>,<4,26>),
            @comments=()
          ])[
          @location=|file://-|(70,13,<4,13>,<4,26>),
          @comments=()
        ])[
        @location=|file://-|(10,87,<1,10>,<5,13>),
        @comments=()
      ])[
      @location=|file://-|(0,97,<1,0>,<5,13>),
      @comments=()
    ]])[
  @location=|file://-|(0,97,<1,0>,<5,13>),
  @comments=()
]
We get the original program and its abstract syntax tree of type Prog back. In case of doubt, compare this with the result in Func/Parse where we did obtain a parse tree. Next, we try the same from a file:
rascal>load(|std:///demo/lang/Func/programs/F0.func|);
Prog: prog([func(
      "fact",
      ["n"],
      cond(
        leq(
          var("n")[
            @location=|std:///demo/lang/Func/programs/F0.func|(13,1,<1,13>,<1,14>),
            @comments=()
          ],
          nat(1)[
            @location=|std:///demo/lang/Func/programs/F0.func|(18,1,<1,18>,<1,19>),
            @comments=()
          ])[
          @location=|std:///demo/lang/Func/programs/F0.func|(13,6,<1,13>,<1,19>),
          @comments=()
        ],
        nat(1)[
          @location=|std:///demo/lang/Func/programs/F0.func|(38,1,<2,13>,<2,14>),
          @comments=()
        ],
        mul(
          var("n")[
            @location=|std:///demo/lang/Func/programs/F0.func|(70,1,<4,13>,<4,14>),
            @comments=()
          ],
          call(
            "fact",
            [sub(
                var("n")[
                  @location=|std:///demo/lang/Func/programs/F0.func|(79,1,<4,22>,<4,23>),
                  @comments=()
                ],
                nat(1)[
                  @location=|std:///demo/lang/Func/programs/F0.func|(81,1,<4,24>,<4,25>),
                  @comments=()
                ])[
                @location=|std:///demo/lang/Func/programs/F0.func|(79,3,<4,22>,<4,25>),
                @comments=()
              ]])[
            @location=|std:///demo/lang/Func/programs/F0.func|(74,9,<4,17>,<4,26>),
            @comments=()
          ])[
          @location=|std:///demo/lang/Func/programs/F0.func|(70,13,<4,13>,<4,26>),
          @comments=()
        ])[
        @location=|std:///demo/lang/Func/programs/F0.func|(10,87,<1,10>,<5,13>),
        @comments=()
      ])[
      @location=|std:///demo/lang/Func/programs/F0.func|(0,97,<1,0>,<5,13>),
      @comments=()
    ]])[
  @location=|std:///demo/lang/Func/programs/F0.func|(0,97,<1,0>,<5,13>),
  @comments=()
]
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 ask.rascal-mpl.org.