void EmitTestRef(RuleAtom cell) { _gen.Emit(Opcodes.TestXMN); _gen.Emit(cell.Symbol); _gen.Emit(cell.Direction); _gen.Emit(GetOper(cell)); }
void EmitCheck(RuleAtom cell) { _gen.Emit(Opcodes.CheckOMN); _gen.Emit(cell.Symbol); _gen.Emit(cell.Direction); _gen.Emit(GetOper(cell)); }
void EmitFind(RuleAtom cell) { _gen.Emit(Opcodes.FindOM); _gen.Emit(cell.Symbol); _gen.Emit(cell.Direction); _gen.Emit(GetOper(cell)); }
// pattern has no match in the action void CompilePatternOnly(RuleAtom patom) { if (!patom.IsNegated && patom.Symbol.IsObject) { EmitDestroy(patom.Symbol); } }
// create temporary rule subpart info internal RuleAtom CreateRuleCell(string noflag, string direction, string prefix, string ident, ScriptFunctionCall call) { return(RuleAtom.Create(noflag != null, ParseDirection(direction), (ident == null) ? RuleAtom.Empty : (ident == "...") ? RuleAtom.Ellipsis : ParseSymbol(ident), prefix == null ? null : ParseVariable(prefix), call == null ? null : ParseScriptCall(call))); }
void EmitScan(RuleAtom cell, Direction ruledir) { _gen.Emit(Opcodes.ScanOMDN); _gen.Emit(cell.Symbol); _gen.Emit(ruledir); _gen.Emit(cell.Direction); _gen.Emit(GetOper(cell)); }
// matching pattern and action depend on NO or direction void CompilePatternAction(RuleAtom patom, RuleAtom aatom) { if (patom.IsNegated) { CompileActionOnly(aatom); } else if (aatom.IsNegated) { EmitDestroy(aatom.Symbol); // TEST: ->[no x] deletes x } else if (patom.Direction != aatom.Direction) { var newdir = (aatom.Direction == Direction.None) ? Direction.Stationary : aatom.Direction; if (!(GameDef.MoveDirections.Contains(newdir) || newdir == Direction.Stationary || newdir == Direction.RandomDir)) { throw Error.Assert("move {0}", newdir); } EmitSetMove(patom.Symbol, newdir); } }
// action has no match in the pattern: refobject and scriptcall always come here void CompileActionOnly(RuleAtom aatom) { if (aatom.IsFunction) { EmitCreateByFunction(aatom.Call, aatom.Direction); } else if (aatom.Symbol.Kind == SymbolKind.RefObject) { EmitCreateByRef(aatom.Symbol, aatom.Direction); } else { if (aatom.IsNegated) { EmitDestroy(aatom.Symbol); } else { EmitCreate(aatom.Symbol, aatom.Direction); } } }
// a matching atom has the same symbol, negation and random, not necessarily the same direction internal bool Matches(RuleAtom other) { return(other.Symbol == Symbol && other.IsNegated == IsNegated && other.IsEllipsis == IsEllipsis && other.IsRandom == IsRandom); }
///------------------------------------------------------------------------- /// /// Emit fragments /// MatchOperator GetOper(RuleAtom cell) { return(cell.IsNegated ? MatchOperator.No : cell.Symbol.Kind == SymbolKind.Aggregate ? MatchOperator.All : MatchOperator.Any); }