static void DCGGoal(BaseTerm t, ref TermNode body, ref BaseTerm remainder, ref bool embedded) { BaseTerm temp; if (t.IsString || t is Cut) { body.Append(t); } else if (t.HasFunctor(PrologParser.CURL)) { while (t.Arity == 2) { body.Append(t.Arg(0)); t = t.Arg(1); embedded = true; } } else if (t.IsProperList) { temp = new Variable(); t = (t.IsEmptyList) ? temp : ((ListTerm)t).Append(temp); if (embedded) { body.Append(new CompoundTerm(PrologParser.EQ, remainder, t)); embedded = false; } else { ((Variable)remainder).Bind(t); } // in this case, nothing is appended to body, which may be left empty (e.g. t-->[x]) remainder = temp; } else if (t.IsAtom || t.IsCompound) { t = new DcgTerm(t, ref remainder); body.Append(t); } else if (t.IsNamedVar) { IO.Error("Variable not allowed in DCG-clause: {0}", ((NamedVariable)t).Name); } else if (t.IsUnboundTerm) { IO.Error("Unbound variable not allowed in DCG-clause"); } else { IO.Error("Illegal term in DCG-clause: {0}", t); } }
static BaseTerm() { EMPTYLIST = new ListTerm(); NULLCURL = new DcgTerm(); DBNULL = new AtomTerm("db_null"); VAR = new Variable(); verNoMax = 0; varNoMax = 0; NUMVAR = "'$VAR'"; CUT = new Cut(0); FAIL = new AtomTerm("fail"); trace = false; }
// DCG stuff public TermNode ToDCG(ref BaseTerm lhs) // called from parser { TermNode body = new TermNode(); BaseTerm result = null; BaseTerm inVar = new Variable(); BaseTerm inVarSave = inVar; BaseTerm outVar = inVar; lhs = new DcgTerm(lhs, ref outVar); // outVar becomes new term BaseTerm remainder; List <BaseTerm> alternatives = AlternativesToArrayList(); for (int i = 0; i < alternatives.Count; i++) { BaseTerm alt = alternatives[i]; bool embedded = (alternatives.Count > 1); List <BaseTerm> terms = alt.ToTermList(); body.Clear(); remainder = inVarSave; for (int ii = 0; ii < terms.Count; ii++) { DCGGoal(terms[ii], ref body, ref remainder, ref embedded); } // create a term-tree from the array if (i == 0) { result = body.TermSeq(); } else { result = new OperatorTerm(SemiOpDescr, result, body.TermSeq()); } ((Variable)remainder).Bind(outVar); } return((result == null) ? null : result.ToGoalList()); // empty body treated similar to null }
BaseTerm CopyEx(int newVerNo, bool mustBeNamed) { if (IsUnified) { return(ChainEnd().CopyEx(newVerNo, mustBeNamed)); } // A neater solution would be to use overrides for each term subtype. if (this is Variable) { Variable v = (Variable)this; if (newVerNo == v.verNo) { return(v.newVar); } v.verNo = newVerNo; return(v.newVar = (mustBeNamed && this is NamedVariable) ? new NamedVariable(((NamedVariable)v).Name) : new Variable()); } else if (this is CatchOpenTerm) { CatchOpenTerm c = (CatchOpenTerm)this; return(new CatchOpenTerm(c.Id, c.ExceptionClass, c.MsgVar.CopyEx(newVerNo, mustBeNamed), c.SeqNo, c.SaveStackSize)); } else { if (arity == 0) { return(this); } BaseTerm t = null; BaseTerm[] a = new BaseTerm[arity]; for (int i = 0; i < arity; i++) { if (args[i] != null) // may be null for a GapTerm { a[i] = args[i].CopyEx(newVerNo, mustBeNamed); // recursively refresh arguments } } if (this is ListPatternTerm) { t = new ListPatternTerm(a); } else if (this is AltListTerm) { AltListTerm alt = (AltListTerm)this; t = new AltListTerm(alt.LeftBracket, alt.RightBracket, a[0], a[1]); } else if (this is ListTerm) { if (((ListTerm)this).CharCodeString == null) { t = new ListTerm(a[0], a[1]); } else // it's an ISO-style string { t = new ListTerm(((ListTerm)this).CharCodeString); } } else if (this is OperatorTerm) { t = new OperatorTerm(((OperatorTerm)this).od, a); } else if (this is DcgTerm) { t = new DcgTerm(functor, a); } else if (this is WrapperTerm) { t = new WrapperTerm((WrapperTerm)this, a); } else if (this is IntRangeTerm) { t = new IntRangeTerm((IntRangeTerm)this); } else if (this is ListPatternElem) { t = new ListPatternElem(a, ((ListPatternElem)this).downRepFactor, ((ListPatternElem)this).IsNegSearch); } else if (this is CompoundTerm) { t = new CompoundTerm(functor, a); } else { IO.Error("CopyEx(): type '{0}' not handled explicitly", this.GetType()); } return(t); } }