Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
114 lines (94 sloc) 2.66 KB
// REFERENCE: Nemerle.Compiler
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
using Nemerle.Collections;
public class Robot
{
public mutable Orientation : byte;
public mutable X : int;
public mutable Y : int;
public IsDown : bool
{
get { Orientation == 1 }
}
public override ToString () : string
{
$"($X, $Y)"
}
}
public variant Expr {
| MoveBy { steps : int; }
| Left
| Right
| Value { prop : string; }
| If { cond : Expr.Value; then : Expr; els : Expr; }
}
public module Scripts
{
public Run (obj : Robot, expr : Expr) : void
{
def check_value (val) {
System.Convert.ToBoolean (obj.GetType ().GetProperty (val.prop).GetValue (obj, null))
}
match (expr) {
| Expr.MoveBy (steps) =>
match (obj.Orientation) {
| 0 => obj.X += steps
| 1 => obj.Y += steps
| 2 => obj.X -= steps
| _ => obj.Y -= steps
}
| Expr.Left => obj.Orientation = ((obj.Orientation + 3) % 4) :> byte;
| Expr.Right => obj.Orientation = ((obj.Orientation + 1) % 4) :> byte;
| Expr.Value as val => _ = check_value (val)
| Expr.If (val, e1, e2) =>
if (check_value (val))
Run (obj, e1)
else
Run (obj, e2)
}
}
public Run (obj : Robot, name : string) : void
{
def script = GetScript (name);
foreach (e in script) Run (obj, e)
}
public GetScript (name : string) : list [Expr]
{
| "myscript1" =>
[Expr.Right (), Expr.MoveBy (5),
Expr.If (Expr.Value ("IsDown"), Expr.MoveBy (3), Expr.Left ())]
| _ => throw System.ArgumentException ($"unknown script $name")
}
public GenerateRun (obj : PExpr, expr : Expr) : PExpr
{
def check_value (val) {
<[ $obj.$(val.prop : dyn) ]>
}
match (expr) {
| Expr.MoveBy (steps) =>
<[ match ($obj.Orientation) {
| 0 => $obj.X += $(steps : int)
| 1 => $obj.Y += $(steps : int)
| 2 => $obj.X -= $(steps : int)
| _ => $obj.Y -= $(steps : int)
}
]>
| Expr.Left => <[ $obj.Orientation = (($obj.Orientation + 3) % 4) :> byte ]>;
| Expr.Right => <[ $obj.Orientation = (($obj.Orientation + 1) % 4) :> byte ]>;
| Expr.Value as val => <[ _ = $(check_value (val)) ]>
| Expr.If (val, e1, e2) =>
<[ if ($(check_value (val)))
$(GenerateRun (obj, e1))
else
$(GenerateRun (obj, e2))
]>
}
}
}
macro GenerateRun (obj, name : string)
{
def script = Scripts.GetScript (name);
def exprs = NList.Map (script, fun (e) { Scripts.GenerateRun (obj, e) });
<[ { ..$exprs } ]>
}
Jump to Line
Something went wrong with that request. Please try again.