public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(); block.Comment("begin precedence alt -----------"); // todo enter block.BeginScope(); BlockLabel returnLabel = new BlockLabel("return"); BlockLocal oldLeftRecursiveAlts = new BlockLocal(typeof(IParseable)); block.DeclareLocal(oldLeftRecursiveAlts); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); block.StoreLocal(oldLeftRecursiveAlts); ParseGraphNode oldLeftRecursiveAltsForCompiler = state.LeftRecursiveAlts; foreach (PrecedenceAltGroup group in groups) { block.BeginScope(); BlockLocal groupLocal = new BlockLocal(typeof(PrecedenceAltGroup)); block.DeclareLocal(groupLocal); block.Load(group); block.StoreLocal(groupLocal); BlockLabel apply = new BlockLabel("apply"); BlockLabel continueLabel = new BlockLabel("continue"); BlockLocal currentPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(currentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.Dup(); block.StoreLocal(currentPrecedence); block.BranchIfNull(apply); BlockLocal groupPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(groupPrecedence); block.LoadLocal(groupLocal); block.GetProperty(groupLocal.Type.GetProperty("Precedence")); block.Dup(); block.StoreLocal(groupPrecedence); block.BranchIfNull(apply); block.LoadLocal(currentPrecedence); block.GetProperty(currentPrecedence.Type.GetProperty("Group")); block.LoadLocal(groupPrecedence); block.GetProperty(groupPrecedence.Type.GetProperty("Group")); block.BranchIfNotEqual(apply); block.LoadLocal(groupPrecedence); block.LoadLocal(currentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); block.LogicalNot(); block.Call(groupPrecedence.Type.GetMethod("IsLowerThan")); block.BranchIfTrue(continueLabel); block.MarkLabel(apply); block.LoadState(); block.LoadLocal(groupLocal); block.GetProperty(groupLocal.Type.GetProperty("LeftRecursiveParseGraph")); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); state.LeftRecursiveAlts = group.LeftRecursiveParseGraph; block.Emit(group.ParseGraph.Compile(runtime, state)); block.Dup(); BlockLabel no = new BlockLabel("no"); block.BranchIfNo(no); block.LoadState(); block.LoadLocal(oldLeftRecursiveAlts); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); // todo yes block.Branch(returnLabel); block.MarkLabel(no); block.Pop(); block.MarkLabel(continueLabel); block.EndScope(); } block.LoadState(); block.LoadLocal(oldLeftRecursiveAlts); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); state.LeftRecursiveAlts = oldLeftRecursiveAltsForCompiler; block.EndScope(); // todo no block.LoadNo(); block.MarkLabel(returnLabel); block.Comment("end precedence alt -----------"); return(block); }
private void CompileInstantiate(ParserBlock block, BlockLocal start, BlockLocal tree) { block.BeginScope(); Type[] parameterTypes = new Type[1 + Fields.Count]; parameterTypes[0] = typeof(Source); for (int n = 1; n < parameterTypes.Length; n++) { parameterTypes[n] = typeof(object); } ConstructorInfo constructor = Type.GetConstructor(parameterTypes); if (constructor == null) { throw new Exception("Couldn't find constructor for " + Type.FullName); } block.LoadLexer(); block.LoadLocal(start); block.Call(typeof(Lexer).GetMethod("SourceFrom")); BlockLocal fields = new BlockLocal(typeof(Dictionary <string, object>)); block.DeclareLocal(fields); block.LoadLocal(tree); block.GetProperty(typeof(ParseTree).GetProperty("Fields")); block.StoreLocal(fields); for (int n = 0; n < Fields.Count; n++) { block.BeginScope(); BlockLocal fieldValue = new BlockLocal(typeof(object)); block.DeclareLocal(fieldValue); block.LoadLocal(fields); block.Load(Fields[n]); block.LoadLocalAddress(fieldValue); block.Call(fields.Type.GetMethod("TryGetValue")); block.Pop(); block.LoadLocal(fieldValue); block.EndScope(); } block.New(constructor); BlockLocal instance = new BlockLocal(typeof(RuntimeObject)); block.DeclareLocal(instance); block.StoreLocal(instance); // Call Parsed block.Load(0); block.NewArray(typeof(object)); block.BeginScope(); BlockLocal parsedParameters = new BlockLocal(typeof(object[])); block.DeclareLocal(parsedParameters); block.StoreLocal(parsedParameters); block.LoadLocal(instance); block.Load("Parsed"); block.LoadLocal(parsedParameters); block.Load(false); block.Call(typeof(MemberNode).GetMethod("GetMember", new Type[] { typeof(object), typeof(string), typeof(object[]), typeof(bool) })); BlockLabel noParsedMethod = new BlockLabel("noParsedMethod"); block.Dup(); block.BranchIfNull(noParsedMethod); BlockLocal parsedMethod = new BlockLocal(typeof(object)); block.DeclareLocal(parsedMethod); block.StoreLocal(parsedMethod); block.LoadRuntimeState(); block.LoadLocal(parsedMethod); block.LoadLocal(parsedParameters); block.Call(typeof(CallNode).GetMethod("Call", new Type[] { typeof(RuntimeState), typeof(object), typeof(object[]) })); block.Pop(); BlockLabel finishedParsedCall = new BlockLabel("finishedParsedCall"); block.Branch(finishedParsedCall); block.MarkLabel(noParsedMethod); block.Pop(); block.MarkLabel(finishedParsedCall); block.EndScope(); block.LoadLocal(instance); block.New(typeof(ParseTree).GetConstructor(new Type[] { typeof(object) })); block.StoreLocal(tree); block.EndScope(); }
public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(runtime); block.Comment("start of pattern --------------------"); if (simple) { block.Emit(pattern.CompileCall(runtime, state)); } else { BlockLabel returnLabel = new BlockLabel("return"); block.BeginScope(); BlockLocal patternLocal = new BlockLocal(typeof(Pattern)); block.DeclareLocal(patternLocal); block.Load(pattern); block.StoreLocal(patternLocal); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide")); BlockLabel parseNew = new BlockLabel("parseNew"); block.BranchIfNull(parseNew); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide")); block.GetProperty(typeof(ParseTree).GetProperty("Value")); block.Call(typeof(object).GetMethod("GetType")); BlockLocal leftType = new BlockLocal(typeof(Type)); block.DeclareLocal(leftType); block.Dup(); block.StoreLocal(leftType); block.LoadLocal(patternLocal); block.GetProperty(typeof(Pattern).GetProperty("Type")); BlockLocal patternType = new BlockLocal(typeof(Type)); block.DeclareLocal(patternType); block.Dup(); block.StoreLocal(patternType); BlockLabel recurse = new BlockLabel("recurse"); block.BranchIfEqual(recurse); block.LoadLocal(leftType); block.LoadLocal(patternType); block.Call(typeof(Type).GetMethod("IsSubclassOf")); block.BranchIfTrue(recurse); block.Branch(parseNew); block.MarkLabel(recurse); block.Single("left hand side from recursion"); block.LoadLexer(); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSideEndPos")); block.SetProperty(typeof(Lexer).GetProperty("Position")); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide")); block.Branch(returnLabel); block.MarkLabel(parseNew); block.Emit(pattern.CompileCall(runtime, state)); block.MarkLabel(returnLabel); block.EndScope(); } block.Comment("end of pattern ---------------------"); return(block); }
public override Block CompileNew(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(runtime); block.Comment("start of concrete pattern -------------"); BlockLabel returnLabel = new BlockLabel("return"); block.BeginScope(); block.Enter(this, Type.Name); BlockLocal start = block.SavePosition(); BlockLabel notExcluded = new BlockLabel("notExcluded"); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.Load(this); block.Call(typeof(Multiset <Pattern>).GetMethod("Contains")); block.BranchIfFalse(notExcluded); block.No(this, "Excluded"); block.LoadNo(); block.Branch(returnLabel); block.MarkLabel(notExcluded); BlockLocal key = new BlockLocal(typeof(ParserMemoryKey)); block.DeclareLocal(key); block.Load(this); block.LoadLocal(start); block.New(typeof(ParserMemoryKey).GetConstructor(new Type[] { typeof(ConcretePattern), typeof(int) })); block.StoreLocal(key); BlockLocal oldSkipMemoryForLeftRecursion = new BlockLocal(typeof(bool)); block.DeclareLocal(oldSkipMemoryForLeftRecursion); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion")); block.Dup(); block.StoreLocal(oldSkipMemoryForLeftRecursion); BlockLabel checkMemory = new BlockLabel("checkMemory"); block.BranchIfFalse(checkMemory); block.LoadState(); block.Load(false); block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion")); BlockLabel setRecursion = new BlockLabel("setRecursion"); block.Branch(setRecursion); block.MarkLabel(checkMemory); block.BeginScope(); BlockLocal entry = new BlockLocal(typeof(ParserMemoryEntry)); block.DeclareLocal(entry); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Memory")); block.LoadLocal(key); block.LoadLocalAddress(entry); block.Call(typeof(Dictionary <ParserMemoryKey, ParserMemoryEntry>).GetMethod("TryGetValue")); block.BranchIfFalse(setRecursion); // todo link next BlockLabel memoryYes = new BlockLabel("memoryYes"); block.LoadLocal(entry); block.GetProperty(typeof(ParserMemoryEntry).GetProperty("Tree")); BlockLabel returnTree = new BlockLabel("returnTree"); block.BranchIfNotNo(memoryYes); block.No(this, start, "from memory"); block.Branch(returnTree); block.MarkLabel(memoryYes); block.Yes(this, start, "from memory"); block.LoadLexer(); block.LoadLocal(entry); block.GetProperty(typeof(ParserMemoryEntry).GetProperty("End")); block.SetProperty(typeof(Lexer).GetProperty("Position")); block.MarkLabel(returnTree); block.LoadLocal(entry); block.GetProperty(typeof(ParserMemoryEntry).GetProperty("Tree")); block.Branch(returnLabel); block.MarkLabel(setRecursion); BlockLocal oldRecursionExclude = new BlockLocal(typeof(ConcretePattern)); block.DeclareLocal(oldRecursionExclude); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude")); block.StoreLocal(oldRecursionExclude); if (RecursionBehaviour != RecursionBehaviour.Recursive) { BlockLabel recursionExcludeSaveNull = new BlockLabel("recursionExcludeSaveNull"); block.LoadLocal(oldRecursionExclude); block.BranchIfNull(recursionExcludeSaveNull); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.LoadLocal(oldRecursionExclude); block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) })); block.MarkLabel(recursionExcludeSaveNull); block.LoadState(); block.Load(this); block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude")); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.Load(this); block.Call(typeof(Multiset <Pattern>).GetMethod("Add", new Type[] { typeof(Pattern) })); } BlockLocal oldRecursionBehaviour = new BlockLocal(typeof(RecursionBehaviour)); block.DeclareLocal(oldRecursionBehaviour); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("RecursionBehaviour")); block.StoreLocal(oldRecursionBehaviour); block.LoadState(); block.Load(Convert.ToInt32(RecursionBehaviour)); block.SetProperty(typeof(ParserState).GetProperty("RecursionBehaviour")); RecursionBehaviour oldRecursionBehaviourState = state.RecursionBehaviour; state.RecursionBehaviour = RecursionBehaviour; BlockLocal oldCurrentPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(oldCurrentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.StoreLocal(oldCurrentPrecedence); BlockLabel doesntOverwrite = new BlockLabel("doesntOverwrite"); block.Load(Precedence); block.LoadLocal(oldCurrentPrecedence); block.Call(typeof(Precedence).GetMethod("Overwrites")); block.BranchIfFalse(doesntOverwrite); block.LoadState(); block.Load(Precedence); block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.MarkLabel(doesntOverwrite); BlockLocal oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool)); block.DeclareLocal(oldPrecedenceCanEqualCurrent); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); block.StoreLocal(oldPrecedenceCanEqualCurrent); block.LoadState(); block.Load(RecursionBehaviour == RecursionBehaviour.Recursive); block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); BlockLocal tree = new BlockLocal(typeof(ParseTree)); block.DeclareLocal(tree); block.Emit(ParseGraph.Compile(runtime, state)); block.StoreLocal(tree); block.LoadState(); block.LoadLocal(oldCurrentPrecedence); block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.LoadState(); block.LoadLocal(oldPrecedenceCanEqualCurrent); block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); block.LoadState(); block.LoadLocal(oldRecursionBehaviour); block.SetProperty(typeof(ParserState).GetProperty("RecursionBehaviour")); state.RecursionBehaviour = oldRecursionBehaviourState; block.LoadState(); block.LoadLocal(oldRecursionExclude); block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude")); block.LoadState(); block.LoadLocal(oldSkipMemoryForLeftRecursion); block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion")); if (RecursionBehaviour != RecursionBehaviour.Recursive) { BlockLabel recursionExcludeRestoreNull = new BlockLabel("recursionExcludeRestoreNull"); block.LoadLocal(oldRecursionExclude); block.BranchIfNull(recursionExcludeRestoreNull); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.LoadLocal(oldRecursionExclude); block.Call(typeof(Multiset <Pattern>).GetMethod("Add", new Type[] { typeof(Pattern) })); block.MarkLabel(recursionExcludeRestoreNull); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.Load(this); block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) })); } BlockLabel no = new BlockLabel("yes1"); block.LoadLocal(tree); block.BranchIfNo(no); block.Whitespace(runtime, state); CompileInstantiate(block, start, tree); block.MarkLabel(no); BlockLocal nextTag = new BlockLocal(typeof(object)); block.DeclareLocal(nextTag); block.New(typeof(object)); block.StoreLocal(nextTag); // todo tag next BlockLabel yes = new BlockLabel("yes"); block.LoadLocal(tree); block.BranchIfNotNo(yes); block.No(this, start, "a"); BlockLabel finish = new BlockLabel("finish"); block.Branch(finish); block.MarkLabel(yes); block.Yes(this, start); if (RecursionBehaviour == RecursionBehaviour.LeftRecursive) { CompileLeftRecurse(runtime, state, block, start, tree); } block.MarkLabel(finish); if (ShouldRemember) { // TODO - can remove some other code if not remembering block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Memory")); block.LoadLocal(key); block.LoadLocal(tree); block.LoadLexer(); block.GetProperty(typeof(Lexer).GetProperty("Position")); block.LoadLocal(nextTag); block.New(typeof(ParserMemoryEntry).GetConstructor(new Type[] { typeof(ParseTree), typeof(int), typeof(object) })); block.SetProperty(typeof(Dictionary <ParserMemoryKey, ParserMemoryEntry>).GetProperty("Item")); } block.LoadLocal(tree); block.EndScope(); block.MarkLabel(returnLabel); block.Comment("end of concrete pattern -------------"); return(block); }