public virtual void EmitInstructions(ParseScope DeclarationScope, VirtualMachine.InstructionList Into) { if (Instructions != null) throw new InvalidOperationException("Instructions should not be emitted twice"); CleanupPoint = Into.Count; if (CleanupCall >= 0) Into[CleanupCall] = CleanupPoint; Into.AddInstructions("CLEANUP NEXT #Cleanup " + Name, DeclarationScope.Owner.ActualParameterCount, "RETURN POP"); Instructions = Into; EntryPoint = Into.Count; Instructions.AddInstructions("MOVE F PUSH #Enter " + Name, "MARK_STACK F"); Body.Emit(Instructions, Ast.OperationDestination.Discard); //Instructions.AddInstructions("MOVE NEXT R", 0); //If a function has no return statement, it returns 0. var returnJumpPoint = Instructions.Count; Instructions.AddInstructions( "RESTORE_STACK F", "MOVE POP F", "RETURN POP"); System.Diagnostics.Debug.Assert(DeclarationScope.Type == ScopeType.Function); System.Diagnostics.Debug.Assert(DeclarationScope.ReturnJumpSources != null); foreach (var point in DeclarationScope.ReturnJumpSources) Instructions[point] = returnJumpPoint; }
public Declaration CompileDeclaration(String script) { Context.ID = 0; var stream = new TokenStream(new StringIterator(script), Context); var declaration = Parse.ParseMacroDeclaration(stream, Context); declaration.ResolveTypes(Context.ActiveScope); declaration.Transform(0); var instructionStream = new VirtualMachine.InstructionList(); declaration.Emit(instructionStream); declaration.ResolveCallPoints(); instructionStream.StringTable.Compress(); if (Compile.Debug) { Compile.EmitDebugDump(declaration); Compile.DebugWrite("\n"); Compile.DebugWrite("\nCOMPILED CODE:\n"); VirtualMachine.Debug.DumpOpcode(instructionStream.Data, Compile.DebugWrite, 1); Compile.DebugWrite(" STRING TABLE:\n"); for (int i = 0; i < instructionStream.StringTable.PartTable.Length; ++i) Compile.DebugWrite(" " + i.ToString() + ": " + instructionStream.StringTable.PartTable[i] + "\n"); Compile.DebugWrite(" STRING DATA:\n"); Compile.DebugWrite(" " + instructionStream.StringTable.StringData + "\n"); } return declaration; }
public void EmitDeclarations(int StaticVariableOffset) { var into = new VirtualMachine.InstructionList(); for (int i = 0; i < TopScope.Types.Count; ++i) { var type = TopScope.Types[i]; type.ID = i; type.ResolveTypes(TopScope); } foreach (var type in TopScope.Types) type.ResolveTypes(TopScope); foreach (var type in TopScope.Types) type.AssignMemberOffsets(); int variableOffset = StaticVariableOffset; foreach (var variable in TopScope.Variables) { //System.Diagnostics.Debug.Assert(variable.StorageMethod == VariableStorageMethod.Static); variable.Offset = variableOffset; ++variableOffset; variable.ResolveType(TopScope); } foreach (var rulebook in Rules.Rulebooks) { rulebook.ResultType = TopScope.FindType(rulebook.ResultTypeName); if (rulebook.ResultType == null) throw new CompileError("Could not find type '" + rulebook.ResultTypeName + "'."); if (rulebook.ResultTypeName == "VOID") throw new CompileError("Rules cannot return void."); if (rulebook.ResultTypeName != "RULE-RESULT") { if (rulebook.DefaultValue == null) throw new CompileError("Rules that return values must have a default value specified using 'default of rule..'"); } //Create consider implementation for rulebook rulebook.ConsiderFunction = new Declaration(); rulebook.ConsiderFunction.Terms = new List<DeclarationTerm>(); rulebook.ConsiderFunction.Terms.Add(new DeclarationTerm { Type = DeclarationTermType.Keyword, Name = "CONSIDER-IMPLEMENTATION" }); rulebook.ConsiderFunction.Terms.AddRange(rulebook.DeclarationTerms); rulebook.ConsiderFunction.ReturnTypeName = rulebook.ResultTypeName; rulebook.ConsiderFunction.Body = new LambdaBlock( new StandardLibrary.ConsiderRuleBookFunctionNode(new Token(), rulebook)); rulebook.ConsiderFunction.OwnerContextID = ID; rulebook.ConsiderFunction.Type = DeclarationType.Rule; PendingEmission.Add(rulebook.ConsiderFunction); foreach (var rule in rulebook.Rules) { foreach (var term in rule.Terms) { if (term.Type == DeclarationTermType.Term && String.IsNullOrEmpty(term.DeclaredTypeName)) { var global = TopScope.FindVariable(term.Name); if (global != null && global.StorageMethod == VariableStorageMethod.Static) { term.DeclaredTypeName = global.DeclaredType.Name; term.DeclaredType = global.DeclaredType; term.IsGlobalReference = true; } } } } } foreach (var macro in TopScope.Macros) macro.ResolveTypes(TopScope); foreach (var declaration in PendingEmission) { if (declaration.Type == DeclarationType.Macro) TopScope.Macros.Add(declaration); declaration.ResolveTypes(TopScope); } foreach (var rulebook in Rules.Rulebooks) { var ruleList = new List<Declaration>(rulebook.Rules); var firstList = new List<Declaration>(); var neutralList = new List<Declaration>(); var lastList = new List<Declaration>(); rulebook.Rules.Clear(); foreach (var rule in ruleList) { if ((rule.OrderOperator & OrderOperator.FIRST) == OrderOperator.FIRST) AddToRulelist(rule, firstList); else if ((rule.OrderOperator & OrderOperator.LAST) == OrderOperator.LAST) AddToRulelist(rule, lastList); else AddToRulelist(rule, neutralList); } rulebook.Rules.AddRange(firstList); rulebook.Rules.AddRange(neutralList); rulebook.Rules.AddRange(lastList); } foreach (var declaration in PendingEmission) declaration.Transform(ID); foreach (var declaration in PendingEmission) { declaration.Emit(into); if (Compile.Debug) { Compile.EmitDebugDump(declaration); Compile.DebugWrite("\n"); } } foreach (var declaration in PendingEmission) declaration.ResolveCallPoints(); into.StringTable.Compress(); if (Compile.Debug) { Compile.DebugWrite("\nCOMPILED CODE:\n"); VirtualMachine.Debug.DumpOpcode(into.Data, Compile.DebugWrite, 1); Compile.DebugWrite(" STRING TABLE:\n"); for (int i = 0; i < into.StringTable.PartTable.Length; ++i) Compile.DebugWrite(" " + i.ToString() + ": " + into.StringTable.PartTable[i] + "\n"); Compile.DebugWrite(" STRING DATA:\n"); Compile.DebugWrite(" " + into.StringTable.StringData + "\n"); Compile.DebugWrite("\n RULE ORDER:\n"); foreach (var rulebook in Rules.Rulebooks) { Compile.DebugWrite("\nRULE " + Declaration.CreateDescriptiveHeader(rulebook.DeclarationTerms, rulebook.ResultTypeName) + ":\n"); foreach (var rule in rulebook.Rules) Compile.DebugWrite(rule.DescriptiveHeader + "\n"); if (rulebook.DefaultValue != null) Compile.DebugWrite("DEFAULT " + rulebook.DefaultValue.DescriptiveHeader + "\n"); } } PendingEmission.Clear(); }
public ExecutionLocation(InstructionList Code, int InstructionPointer) { this.Code = Code; this.InstructionPointer = InstructionPointer; }