private bool ProcessCurrentInstruction(CoroutineGroup group) { if (CurrentInstruction != null) { if (!ProcessInstruction(CurrentInstruction, group)) { return(false); } CurrentInstruction = null; } while (injectedInstructionQueue != null && injectedInstructionQueue.Count > 0) { CurrentInstruction = injectedInstructionQueue.Dequeue(); CurrentInstruction.Begin(); IsCurrentInstructionInjected = true; if (!ProcessInstruction(CurrentInstruction, group)) { return(false); } } IsCurrentInstructionInjected = false; return(true); }
private string findLabel() { RemoveSpaces(CurrentInstruction); string tempString = ""; bool foundValue = false; bool doneFinding = false; for (int j = 0; j < CurrentInstruction.Length; j++) { char temp = CurrentInstruction.ElementAt(j); if (foundValue && (temp == ' ' || temp == '\t') && !doneFinding) { doneFinding = true; } else if (foundValue && temp != ' ' && temp != '\t' && doneFinding) { gui.ReportError("Error: Unexpected text after value"); } else if (!foundValue && temp != ' ' && temp != '\t') { foundValue = true; tempString = tempString + temp; } else if (foundValue && temp != ' ' && temp != '\t') { tempString = tempString + temp; } } return(tempString); }
protected override void DetectionReaction(GameObject[] target) { foreach (GameObject potentialEnemy in target) { Destructible enemy = potentialEnemy.GetComponent <Destructible>(); if (enemy != null) { if (!enemy.IsDead()) { if (CurrentInstruction == null) { Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } else if (CurrentInstruction.GetType() != typeof(Attack)) { Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } } } } }
protected override void ExecuteInternal(IExecutionEnvironment environment, IList <IInstruction> instructions) { CurrentInstruction.Execute(environment); if (CurrentInstruction is BranchAndExchangeInstruction baeInstruction) { // TODO: Implement thumb mode if (baeInstruction.IsThumbMode) { throw new InvalidOperationException("Thumb mode is not supported."); } } if (!(environment.CpuState is Aarch32CpuState armCpuState)) { throw new InvalidOperationException("CpuState is not supported."); } // If a branch was executed if (CurrentInstruction is BranchInstruction branchInstruction && branchInstruction.IsBranching) { // Clear buffer and and get 2 new instructions from new PC _instructionBuffer.Clear(); // Buffer next 2 instructions GetNextInstruction(environment, instructions); GetNextInstruction(environment, instructions); }
protected override void DetectionReaction(GameObject[] target) { foreach (GameObject potentialEnemy in target) { Destructible enemy = potentialEnemy.GetComponent <Destructible>(); if (enemy != null) { if (!enemy.IsDead()) { // TODO: properly detect if enemy is dead? if (CurrentInstruction == null) { Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); //Instructions.Push(new Goto(this.transform.position, 0, this)); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } else if (CurrentInstruction.GetType() == typeof(Chase)) { Instructions.Pop(); Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } else if (CurrentInstruction.GetType() != typeof(Attack)) { Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } } } } }
public void ReadInstruction(int line, bool section) { CurrentInstruction = section ? InputText[line] : InputData[line]; if (CurrentInstruction.Contains("#")) { CurrentInstruction = CurrentInstruction.Substring(0, CurrentInstruction.IndexOf("#")); } CurrentLine = line; }
private bool assertRemoveComma() { if (CurrentInstruction.Length < 2 || CurrentInstruction.ElementAt(0) != ',') { gui.ReportError("Error: Comma expected"); return(false); } CurrentInstruction = CurrentInstruction.Substring(1); return(true); }
public int ExecuteNext() { var(move, increase) = CurrentInstruction.Execute(); Position += move; Accumulator += increase; if (Position > LoadedProgram.Count - 1) { RanToCompletion = true; } return(Accumulator); }
public void Process(CoroutineGroup group) { if (IsPaused) { return; } if (!ProcessCurrentInstruction(group)) { return; } if (Enumerator == null) { FMessage.Log(ELogVerbosity.Error, "Coroutine enumerator is null"); Stop(); return; } try { while (Enumerator.MoveNext()) { object current = Enumerator.Current; YieldInstruction instruction = current as YieldInstruction; if (instruction != null) { CurrentInstruction = instruction; CurrentInstruction.Owner = this; CurrentInstruction.Begin(); if (!ProcessCurrentInstruction(group)) { return; } } else { return; } } } catch (Exception e) { FMessage.Log(ELogVerbosity.Error, "Exception when running coroutine. " + Environment.NewLine + e.ToString()); Stop(); return; } Complete = true; }
public override void TakeDamage(int damage, Vector3 origin = default(Vector3)) { base.TakeDamage(damage); if (!IsDead() && origin != default && (CurrentInstruction.GetType() != typeof(Attack) && CurrentInstruction.GetType() != typeof(Chase))) { Instructions.Push(CurrentInstruction); if (origin != default) { CurrentInstruction = new Goto(origin, 2, this); } } }
public bool Step() { if (quit) { return(false); } CurrentInstruction = Environment.Delegate.instructions[Environment.ProgramCounter]; #if DEBUG Environment.AddHistoryEntry(CurrentInstruction); #endif try { CurrentInstruction.Execute(Environment); } catch (ScriptException e) { HandleException(e, Environment); } catch (TargetInvocationException e) { HandleException(new ScriptException(CurrentInstruction, e.InnerException), Environment); } catch (Exception e) { HandleException(new ScriptException(CurrentInstruction, e), Environment); } if (Environment.ProgramCounter < -1 || Environment.ProgramCounter >= Environment.Delegate.instructions.Length) { throw new ScriptException(CurrentInstruction, new IndexOutOfRangeException()); } Environment.ProgramCounter++; if (Environment.IsReturning || Environment.ProgramCounter >= Environment.Delegate.instructions.Length) { quit = true; return(false); } return(true); }
public PipelineExecutionMessage Clone() { var pem = new PipelineExecutionMessage() { BinaryPayload = BinaryPayload, CompletionTimeStamp = CompletionTimeStamp, CreationTimeStamp = CreationTimeStamp, Device = Device, ErrorMessages = ErrorMessages, ErrorReason = ErrorReason, ExecutionTimeMS = ExecutionTimeMS, Id = Id, InfoMessages = InfoMessages, InputCommand = InputCommand, Log = Log, MediaItemId = MediaItemId, MessageId = MessageId, MessageType = MessageType, OutgoingMessages = OutgoingMessages, OutputCommands = OutputCommands, PayloadLength = PayloadLength, PayloadType = PayloadType, ResponseMessage = ResponseMessage, Status = Status, TextPayload = TextPayload, WarningMessages = WarningMessages, }; foreach (var instruction in Instructions) { pem.Instructions.Add(instruction); } if (CurrentInstruction != null) { pem.CurrentInstruction = CurrentInstruction.Clone(); } if (Envelope != null) { pem.Envelope = Envelope.Clone(); } return(pem); }
protected override void DetectionReaction(GameObject[] target) { GameObject threat = Array.Find(target, potentialTarget => potentialTarget.GetComponent <Destructible>().CurrentGrowth == (int)Destructible.Sizes.Large); if (threat != null && this.SpookLevel != ReportState.Attacking) { canAttack = false; NumberOfSoldiersToSend = largeResponse; Instructions.Clear(); Instructions.Push(new Interact(barracks, this)); CurrentInstruction = new Goto(barracks.transform.position, 0, this); reportPosition = threat.transform.position; return; } foreach (GameObject potentialEnemy in target) { Destructible enemy = potentialEnemy.GetComponent <Destructible>(); if (enemy != null) { if (!enemy.IsDead()) { if (CurrentInstruction == null) { // Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); //Instructions.Push(new Goto(this.transform.position, 0, this)); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } else if (CurrentInstruction.GetType() == typeof(Chase)) { Instructions.Pop(); // Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } else if (CurrentInstruction.GetType() != typeof(Attack)) { //Debug.Log(enemy + " has a tag " + target[0].gameObject.layer); TargetAcquired(target[0].gameObject.GetComponent <Destructible>()); break; } } } } }
private bool FindRegister(int num) { bool foundRegister = false; if (CurrentInstruction.ElementAt(0) != '$' || CurrentInstruction.Length < 2) { gui.ReportError("Error: Register expected"); return(foundRegister); } CurrentInstruction = CurrentInstruction.Substring(1); string register = CurrentInstruction.Substring(0, 2); if (register == "ze" && CurrentInstruction.Length >= 4) { register += CurrentInstruction.Substring(2, 2); } else if (register == "ze") { gui.ReportError("Error: Register expected"); return(foundRegister); } register = "$" + register; for (int i = 0; i < Registers.Count; i++) { if (register == Registers[i].Label) { args[num] = i; foundRegister = true; if (i != 0) { CurrentInstruction = CurrentInstruction.Substring(2); } else { CurrentInstruction = CurrentInstruction.Substring(4); } } } if (!foundRegister) { gui.ReportError("Error: Invalid register"); } return(foundRegister); }
public void InjectInstruction(YieldInstruction instruction, YieldInstructionInjectType injectType = YieldInstructionInjectType.Queue) { instruction.Owner = this; if (instruction.running) { throw new InvalidOperationException("Cannot inject an already running instruction."); } if (CurrentInstruction != null) { if (injectType == YieldInstructionInjectType.RemoveCurrent) { // ReleasePooledInstruction will call instruction.End() for us of already running ReleaseInstruction(CurrentInstruction); CurrentInstruction = instruction; CurrentInstruction.Begin(); } else if (injectType == YieldInstructionInjectType.SwapCurrent) { if (CurrentInstruction.running) { CurrentInstruction.End(); } CurrentInstruction = instruction; CurrentInstruction.Begin(); } else { if (injectedInstructionQueue == null) { injectedInstructionQueue = new Queue <YieldInstruction>(); } injectedInstructionQueue.Enqueue(instruction); } } else { CurrentInstruction = instruction; } }
protected void Update() { if (CurrentInstruction != null) { CurrentInstruction.Execute(); } else { GetNextInstruction(); } if (CurrentInstruction == null) { return; } else if ((CurrentInstruction.GetType() != typeof(Attack) && CurrentInstruction.GetType() != typeof(FixBreaker) && CurrentInstruction.GetType() != typeof(CreateNest) && CurrentInstruction.GetType() != typeof(CreateQueen)) && isWalking == true) { isWalking = false; StartCoroutine(walkingLoop()); } }
public override void TakeDamage(int damage, Vector3 origin = default(Vector3)) { base.TakeDamage(damage); if (!IsDead() && origin != default && (CurrentInstruction.GetType() != typeof(Attack) && CurrentInstruction.GetType() != typeof(Chase))) { callSmallAliens(origin); } }
private void ExecuteInstruction(Instruction instruction) { CurrentInstruction.Visit(); _actions[instruction.Name](instruction.Arg); }
private int ParseInstruction() { int i = 0, j = 0; //temp vars RemoveSpaces(CurrentInstruction); if (CurrentInstruction.Contains(":")) { return(-2); } if (CurrentInstruction.Length < 4) { gui.ReportError("Error: Unknown operation"); return(-2); } for (j = 0; j < CurrentInstruction.Length; j++) { var temp = CurrentInstruction.ElementAt(j); if (temp == ' ' || temp == '\t') { break; } } string op = CurrentInstruction.Substring(0, j); if (CurrentInstruction.Length > 0 && j < CurrentInstruction.Length - 1) { CurrentInstruction = CurrentInstruction.Substring(j + 1); } int OperationID = -1; for (i = 0; i < InstructionSet.Length; i++) { if (op == InstructionSet[i]) { OperationID = i; break; } } if (OperationID == -1) { gui.ReportError("Error:Unknown operation"); return(-2); } if (OperationID < 13) // R Format { for (int count = 0; count < 3 - (OperationID > 8 ? 1 : 0); count++) { RemoveSpaces(CurrentInstruction); if (!FindRegister(count)) { return(-2); } RemoveSpaces(CurrentInstruction); if (count == 2 - (OperationID > 8 ? 1 : 0)) { break; } if (!assertRemoveComma()) { return(-2); } } if (CurrentInstruction != "") { gui.ReportError("Error: Extra arguments provided"); return(-2); } } else if (OperationID < 17) // I format { for (int count = 0; count < 2; count++) { RemoveSpaces(CurrentInstruction); FindRegister(count); RemoveSpaces(CurrentInstruction); assertRemoveComma(); } RemoveSpaces(CurrentInstruction); string tempString = findLabel(); int temp; if (!int.TryParse(tempString, out temp)) { gui.ReportError("Error: Not a valid Immediate argument"); return(-2); } args[2] = temp; } else if (OperationID < 21) // lw sw ldc1 sdc1 { string tempString = ""; int offset; RemoveSpaces(CurrentInstruction); FindRegister(0); RemoveSpaces(CurrentInstruction); assertRemoveComma(); RemoveSpaces(CurrentInstruction); if ((CurrentInstruction.ElementAt(0) > 47 && CurrentInstruction.ElementAt(0) < 58) || CurrentInstruction.ElementAt(0) == '-') { j = 0; while (j < CurrentInstruction.Length && CurrentInstruction.ElementAt(j) != ' ' && CurrentInstruction.ElementAt(j) != '\t' && CurrentInstruction.ElementAt(j) != '(') { tempString = tempString + CurrentInstruction.ElementAt(j); j++; } if (j == CurrentInstruction.Length) { gui.ReportError("Error: '(' expected"); return(-2); } int temp; if (!int.TryParse(tempString, out temp)) { gui.ReportError("Error: not a valid offset"); return(-2); } offset = temp; CurrentInstruction = CurrentInstruction.Substring(j); RemoveSpaces(CurrentInstruction); if (CurrentInstruction == "" || CurrentInstruction.ElementAt(0) != '(' || CurrentInstruction.Length < 2) { gui.ReportError("Error: '(' expected"); return(-2); } CurrentInstruction = CurrentInstruction.Substring(1); RemoveSpaces(CurrentInstruction); FindRegister(1); RemoveSpaces(CurrentInstruction); if (CurrentInstruction == "" || CurrentInstruction.ElementAt(0) != ')') { gui.ReportError("Error: ')' expected"); return(-2); } CurrentInstruction = CurrentInstruction.Substring(1); OnlySpaces(0, CurrentInstruction.Length, CurrentInstruction); args[2] = offset; if (args[2] == -1) { gui.ReportError("Error: invalid offset"); return(-2); } } else //label { tempString = findLabel(); bool foundLocation = false; for (j = 0; j < MemoryTable.Count; j++) { if (tempString == MemoryTable[j].Label) { foundLocation = true; args[1] = j; break; } } if (!foundLocation) { gui.ReportError("Error: invalid label"); return(-2); } args[2] = -1; } } else if (OperationID < 23) // beq blt { for (int count = 0; count < 2; count++) { RemoveSpaces(CurrentInstruction); FindRegister(count); RemoveSpaces(CurrentInstruction); assertRemoveComma(); } RemoveSpaces(CurrentInstruction); string tempString = findLabel(); bool found = false; for (j = 0; j < LabelTable.Count; j++) { if (tempString == LabelTable[j].Label) { found = true; args[2] = LabelTable[j].Address; break; } } if (!found) { gui.ReportError("Error: invalid label"); return(-2); } } else if (OperationID < 26) // j bclt bclf { RemoveSpaces(CurrentInstruction); bool found = false; string tempString = findLabel(); for (j = 0; j < LabelTable.Count; j++) { if (tempString == LabelTable[j].Label) { found = true; args[0] = LabelTable[j].Address; } } if (!found) { gui.ReportError("Error: invalid label"); return(-2); } } else if (OperationID < 28) // mflo mfhi { RemoveSpaces(CurrentInstruction); if (!FindRegister(0)) { return(-2); } if (!OnlySpaces(0, CurrentInstruction.Length, CurrentInstruction)) { return(-2); } } return(OperationID); }
public void Preprocess() { int current_section = -1; if (InputData.Count != 0) { current_section = 0; } int LabelIndex; if (current_section == 0) { for (int i = 0; i < InputData.Count; i++) { ReadInstruction(i, false); CurrentInstruction = RemoveSpaces(CurrentInstruction); if (CurrentInstruction == "") { continue; } LabelIndex = CurrentInstruction.IndexOf(':'); if (LabelIndex == -1) { break; } if (LabelIndex == 0) { gui.ReportError("Error: Label name expected"); return; } int j = LabelIndex - 1; while (j > 0 && (CurrentInstruction.ElementAt(j) == ' ' || CurrentInstruction.ElementAt(j) == '\t')) { j--; } string tempString = ""; bool doneFlag = false; for (; j >= 0; j--) { char tempChar = CurrentInstruction.ElementAt(j); if (tempChar != ' ' && tempChar != '\t' && !doneFlag) { tempString = tempChar + tempString; } else if (tempChar != ' ' && tempChar != '\t' && doneFlag) { gui.ReportError("Error: Unexpected text before label name"); return; } else { doneFlag = true; } } if (!assertLabelAllowed(tempString)) { return; } MemoryData tempMemory = new MemoryData(); tempMemory.Label = tempString; int wordIndex = CurrentInstruction.IndexOf(".word"); // TODO: Add directives for .float int floatIndex = CurrentInstruction.IndexOf(".float"); if (!(floatIndex != -1 || wordIndex != -1)) { gui.ReportError("Error: .word or .float not found"); return; } bool floatFlag; int Index; if (wordIndex == -1) { floatFlag = true; Index = floatIndex; } else { floatFlag = false; Index = wordIndex; } tempMemory.floatFlag = floatFlag; if (tempMemory.floatFlag) { MemoryData.StaticMemory += 4; } if (!OnlySpaces(LabelIndex + 1, Index, CurrentInstruction)) { return; } bool foundValue = false; bool doneFinding = false; tempString = ""; for (j = Index + (floatFlag ? 6 : 5); j < CurrentInstruction.Length; j++) { char temp = CurrentInstruction.ElementAt(j); if (foundValue && (temp == ' ' || temp == '\t') && !doneFinding) { doneFinding = true; } else if (foundValue && temp != ' ' && temp != '\t' && doneFinding) { gui.ReportError("Error: Unexpected text after value"); return; } else if (!foundValue && temp != ' ' && temp != '\t') { foundValue = true; tempString = tempString + temp; } else if (foundValue && temp != ' ' && temp != '\t') { tempString = tempString + temp; } } if (floatFlag) { double tempValue; if (!double.TryParse(tempString, out tempValue)) { gui.ReportError("Error: Float conversion error"); return; } tempMemory.Value = tempString; } else { int tempValue; if (!int.TryParse(tempString, out tempValue)) { gui.ReportError("Error: Int conversion error"); return; } tempMemory.Value = tempString; } MemoryTable.Add(tempMemory); } } MemoryTable.Sort(delegate(MemoryData m1, MemoryData m2) { return(m1.Label.CompareTo(m2.Label)); }); for (int i = 0; i < MemoryTable.Count - 1; i++) { if (MemoryTable.ElementAt(i) == MemoryTable.ElementAt(i + 1)) { gui.ReportError("Error: One or more labels are repeated"); return; } } if (InputText.Count != 0) { current_section = 1; } if (current_section != 1) { gui.ReportError("Error: Text section does not exist or found unknown string"); return; } int MainIndex = 0; bool FoundMain = false; LabelIndex = 0; for (int i = 0; i < InputText.Count; i++) { ReadInstruction(i, true); if (CurrentInstruction == "") { continue; } LabelIndex = CurrentInstruction.IndexOf(":"); if (LabelIndex == 0) { gui.ReportError("Error: Label name expected"); return; } if (LabelIndex == -1) { continue; } int j = LabelIndex - 1; while (j > 0 && CurrentInstruction.ElementAt(j) == ' ' && CurrentInstruction.ElementAt(j) == '\t') { j--; } string tempString = ""; bool isLabel = false; bool doneFlag = false; for (; j >= 0; j--) { char temp = CurrentInstruction.ElementAt(j); if (temp != ' ' && temp != '\t' && !doneFlag) { isLabel = true; tempString = temp + tempString; } else if (temp != ' ' && temp != '\t' && doneFlag) { gui.ReportError("Error: Unexpected text before label name"); return; } else if (!isLabel) { gui.ReportError("Error: Label name expected"); return; } else { doneFlag = true; } } if (!assertLabelAllowed(tempString)) { return; } if (!OnlySpaces(LabelIndex + 1, CurrentInstruction.Length, CurrentInstruction)) { return; } if (tempString == "main") { FoundMain = true; MainIndex = CurrentLine; } else { LabelData tempLabel = new LabelData();; tempLabel.Address = CurrentLine; tempLabel.Label = tempString; LabelTable.Add(tempLabel); } } LabelTable.Sort(delegate(LabelData l1, LabelData l2) { return(l1.Label.CompareTo(l2.Label)); }); for (int i = 0; LabelTable.Count > 0 && i < LabelTable.Count - 1; i++) { if (LabelTable[i].Label == LabelTable[i + 1].Label) { gui.ReportError("Error: One or more labels are repeated"); return; } } if (!FoundMain) { gui.ReportError("Error: Could not find main"); return; } CurrentLine = MainIndex; gui.SendLog("Initialized and ready to execute."); gui.updateState(); }
/// <summary> /// The first pass for the assembler /// </summary> private void FirstPass(string[] lines, List <string[]> splitedLines, Dictionary <string, uint> symbolTable, Dictionary <string, DefinedDataVariable> dataVariables, HashSet <string> functions) { int currentLineNum = 0; AssemblerMode mode = AssemblerMode.Text; for (int i = 0; i < lines.Length; i++) { string currentLine = lines[i]; //Get the instruction and operands string[] instructionAndOperands = ExtractInstructionAndOperands(RemoveComments(currentLine)); //Ignore empty lines if (instructionAndOperands.Length > 0) { bool handled = false; //Must be atleast 1 token if (instructionAndOperands.Length >= 1) { bool skipLine = false; //Check if assembler directive if (instructionAndOperands[0].StartsWith(".")) { if (instructionAndOperands[0] == ".data") { mode = AssemblerMode.Data; handled = true; skipLine = true; } if (instructionAndOperands[0] == ".text") { mode = AssemblerMode.Text; handled = true; skipLine = true; } } //Check if starts with an label if (instructionAndOperands[0].EndsWith(":")) { string label = instructionAndOperands[0].Substring(0, instructionAndOperands[0].Length - 1); if (mode == AssemblerMode.Text) { symbolTable.Add(label, (uint)currentLineNum * 4); //Must be atleast 2 tokens if (instructionAndOperands.Length >= 2) { instructionAndOperands = instructionAndOperands.Skip(1).ToArray(); handled = true; } //Only a label, insert a NOP if (instructionAndOperands.Length == 1) { instructionAndOperands = new string[] { "nop" }; handled = true; } } else { string varType = instructionAndOperands[1]; string varStartValue = instructionAndOperands[2]; int startValue = 0; if (!int.TryParse(varStartValue, out startValue)) { throw new AssemblerException(i, "", "The current start value is not an integer."); } switch (varType) { case ".word": dataVariables.Add(label, new DefinedDataVariable() { StartValue = startValue, DataType = DataType.Word }); break; case ".byte": if (startValue >= 0 && startValue <= 255) { dataVariables.Add(label, new DefinedDataVariable() { StartValue = startValue, DataType = DataType.Byte }); } else { throw new AssemblerException(i, "", "The byte value must be in the range [0, 255]."); } break; default: throw new AssemblerException(i, "", "Unrecognized data variable type '" + varType + "'."); } skipLine = true; handled = true; } } //Check if a marco if (!skipLine && mode == AssemblerMode.Text) { if (macros.ContainsKey(instructionAndOperands[0])) { //Get the macro var macro = macros[instructionAndOperands[0]]; CurrentInstruction currentInstruction = new CurrentInstruction() { LineNumber = i, Operands = instructionAndOperands.Skip(1).ToArray(), }; splitedLines.AddRange(macro(currentInstruction)); handled = true; } else { splitedLines.Add(instructionAndOperands); handled = true; } } } if (!handled) { throw new AssemblerException(i, currentLine, string.Format("Unhandled instruction \"{0}\"", currentLine)); } if (handled) { //Check if call instruction if (instructionAndOperands[0] == "call" && instructionAndOperands.Length == 2) { //Add the called function to the list of functions functions.Add(instructionAndOperands[1]); } } currentLineNum++; } } }
/// <summary> /// The second pass for the assembler /// </summary> private void SecondPass(List <Instruction> instructions, List <string[]> splitedLines, Dictionary <string, uint> symbolTable, HashSet <string> functions, Dictionary <uint, int> functionTable) { //The function table (entry point and sizes for functions, needed for the jitter). bool isFunction = false; uint currentFunc = 0; int funcSize = 0; //Begin the second pass for (int lineNum = 0; lineNum < splitedLines.Count; lineNum++) { string[] currentLine = splitedLines[lineNum]; string instruction = currentLine[0].ToLower(); //Find the decoder if (instructionAssemblers.ContainsKey(instruction)) { //Proccess the operands string[] operands = currentLine.Skip(1).Select(operand => { if (!branchInstructions.Contains(instruction)) { //Check if assembler macro string newOperand = ""; bool isAssemblerMacro = this.ParseAssemblerMacro(lineNum, instruction, symbolTable, operand, out newOperand); if (isAssemblerMacro) { operand = newOperand; } } if (symbolTable.ContainsKey(operand) && !branchInstructions.Contains(instruction)) { //Replace label with its value return(symbolTable[operand].ToString()); } else { return(operand); } }).ToArray(); var instructionDecoder = instructionAssemblers[instruction]; CurrentInstruction currentInstruction = new CurrentInstruction() { LineNumber = lineNum, Operands = operands, SymbolTable = symbolTable }; instructions.Add(instructionDecoder(currentInstruction)); //Check if the symbol table has an entry for the current instruction uint address = (uint)lineNum * 4; if (symbolTable.ContainsValue(address)) { if (!isFunction) { string funcName = this.KeyFor(symbolTable, address); //Check if func if (functions.Contains(funcName)) { isFunction = true; funcSize = 0; currentFunc = address / 4; } } } if (isFunction) { funcSize += 1; if (currentLine[0] == "ret") { isFunction = false; functionTable.Add(currentFunc, funcSize); } } } else { throw new AssemblerException(lineNum, instruction, string.Format("Could not instruction assembler for instruction \"{0}\"", instruction)); } } }
public override void TakeDamage(int damage, Vector3 origin = default(Vector3)) { base.TakeDamage(damage); if (!IsDead() && origin != default && (CurrentInstruction.GetType() != typeof(Attack) && CurrentInstruction.GetType() != typeof(Chase))) { Instructions.Push(CurrentInstruction); if (origin != default) { CurrentInstruction = new Goto(origin, 2, this); } } if (CurrentHealth < 10) { canAttack = false; Instructions.Clear(); Instructions.Push(new Interact(barracks, this)); CurrentInstruction = new Goto(barracks.transform.position, 0, this); reportPosition = origin; } }