Load AST
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 ConcreteSyntax and its abstract syntax in AbstractSyntax. Rather than manually writing conversion rules from Func parse trees to Func abstract syntax trees we use our secret weapon: 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;
demo::lang::Func::AST::Prog implode(demo::lang::Func::Func::Prog p) =
implode(#demo::lang::Func::AST::Prog, p);
demo::lang::Func::AST::Prog load(loc l) = implode(parse(l));
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 gets 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",
src=|unknown:///|(13,1,<1,13>,<1,14>),
comments=()),
nat(
1,
src=|unknown:///|(18,1,<1,18>,<1,19>),
comments=()),
src=|unknown:///|(13,6,<1,13>,<1,19>),
comments=()),
nat(
1,
src=|unknown:///|(38,1,<2,13>,<2,14>),
comments=()),
mul(
var(
"n",
src=|unknown:///|(70,1,<4,13>,<4,14>),
comments=()),
call(
"fact",
[sub(
var(
"n",
src=|unknown:///|(79,1,<4,22>,<4,23>),
comments=()),
nat(
1,
src=|unknown:///|(81,1,<4,24>,<4,25>),
comments=()),
src=|unknown:///|(79,3,<4,22>,<4,25>),
comments=())],
src=|unknown:///|(74,9,<4,17>,<4,26>),
comments=()),
src=|unknown:///|(70,13,<4,13>,<4,26>),
comments=()),
src=|unknown:///|(10,87,<1,10>,<5,13>),
comments=()),
src=|unknown:///|(0,97,<1,0>,<5,13>),
comments=())],
src=|unknown:///|(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 Parse where we did obtain a parse tree.
Next, we try the same from a file:
rascal>load(|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|);
Prog: prog(
[func(
"fact",
["n"],
cond(
leq(
var(
"n",
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(13,1,<1,13>,<1,14>),
comments=()),
nat(
1,
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(18,1,<1,18>,<1,19>),
comments=()),
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(13,6,<1,13>,<1,19>),
comments=()),
nat(
1,
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(38,1,<2,13>,<2,14>),
comments=()),
mul(
var(
"n",
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(70,1,<4,13>,<4,14>),
comments=()),
call(
"fact",
[sub(
var(
"n",
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(79,1,<4,22>,<4,23>),
comments=()),
nat(
1,
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(81,1,<4,24>,<4,25>),
comments=()),
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(79,3,<4,22>,<4,25>),
comments=())],
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(74,9,<4,17>,<4,26>),
comments=()),
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(70,13,<4,13>,<4,26>),
comments=()),
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(10,87,<1,10>,<5,13>),
comments=()),
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(0,97,<1,0>,<5,13>),
comments=())],
src=|project://rascal-website/courses/Recipes/demo/lang/Func/programs/F0.func|(0,97,<1,0>,<5,13>),
comments=())