
/* Defining a macro-like function that declares a function
 * with only one rule.
 */
RuleBase("Function",{oper,args,body});
Bodied("Function");
HoldArg("Function",oper);
HoldArg("Function",args);
HoldArg("Function",body);
Rule("Function",3,0,True)
[
  TryRetract(oper,Length(args)); 
  MacroRuleBase(oper,args);
  MacroRule(oper,Length(args),0,True) body;
];

/* := assignment. */
RuleBase(":=",{aLeftAssign,aRightAssign});
UnFence(":=",2);
HoldArg(":=",aLeftAssign);
HoldArg(":=",aRightAssign);

/* := assignment. */
Rule(":=",2,0,IsAtom(aLeftAssign))
[
  MacroSet(aLeftAssign,Eval(aRightAssign));
];


RuleBase("AssignArray",{setlistterm,setlistindex,setlistresult});
UnFence("AssignArray",3);
Rule("AssignArray",3,1,IsString(setlistindex))
[
  Local(item);
  item:=Assoc(setlistindex,setlistterm);
  If(item = Empty,
     DestructiveInsert(setlistterm,1,{setlistindex,setlistresult}),
     DestructiveReplace(item,2,setlistresult)
     );
  True;
];

Rule("AssignArray",3,1,
   MathAnd(
           Equals(IsGeneric(setlistterm),True),
           Equals(GenericTypeName(setlistterm),"Array")
          )
    )
[
  ArraySet(setlistterm,setlistindex,setlistresult);
];


Rule("AssignArray",3,2,True)
[
  DestructiveReplace(setlistterm ,setlistindex, setlistresult);
  True;
];

Rule(":=",2,10,IsFunction(aLeftAssign) And (aLeftAssign[[0]] = Atom("Nth")))
[
 AssignArray(Eval(aLeftAssign[[1]]),
             Eval(aLeftAssign[[2]]),Eval(aRightAssign));
];
Rule(":=",2,20,IsFunction(aLeftAssign))
[
  Local(oper,args,arity);
  Set(oper,String(aLeftAssign[[0]]));
  Set(args,Tail(Listify(aLeftAssign)));
  Set(arity,Length(args));
  TryRetract(oper,arity); 
  MacroRuleBase(oper, args);
  MacroRule(oper,arity,0,True) aRightAssign;
];



