protected override void GenerateCaseStatement(CodeCaseStatement e)
		{
			TextWriter output = base.Output;
			output.Write("case ");
			GenerateExpression(e.CaseExpression);
			output.Write(":");
			output.WriteLine();
			Indent++;
			GenerateStatements(e.Statements);
			Indent--;
		}
		public void AddRange(CodeCaseStatement[] value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			for (int i = 0; i < value.Length; i++)
			{
				this.Add(value[i]);
			}
		}
		public void WriteConditionalEmit(CodeScopeStatement con, InstructionForm overridenForm, bool ignoreOtherOverrides = false)
		{
			if (Conditions.Count == 0)
				throw new Exception("There are no conditions to the override!");
			if (!ignoreOtherOverrides && CanGenSegmentSwitch(overridenForm))
			{
				CodeSwitchStatement sw = new CodeSwitchStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(),
						overridenForm.GetArgName(FieldTypeRegistry.Segment.ID, 1, Conditions[0].ArgIndexToCheck)
					)
				);
				for (int i = 0; i < overridenForm.Overrides.Count; i++)
				{
					CodeCaseStatement cs = new CodeCaseStatement(
						new CodeFieldReferenceExpression(
							StaticTypeReferences.SegmentExpression,
							overridenForm.Overrides[i].Conditions[0].RegisterToCompareTo
						)
					);
					CodeScopeStatement cst = new CodeScopeStatement();
					overridenForm.Overrides[i].NewForm.WriteEmit(cst, true);
					cst.Statements.Add(new CodeBreakStatement());
					cs.Statements.Add(cst);
					sw.Cases.Add(cs);
				}
				CodeDefaultCaseStatement defStat = new CodeDefaultCaseStatement();
				CodeScopeStatement defCont = new CodeScopeStatement();
				overridenForm.WriteEmit(defCont, true);
				defStat.Statements.Add(defCont);
				if (overridenForm.WriteOperations[0].Type != WriteOperationType.Throw)
				{
					defStat.Statements.Add(new CodeBreakStatement());
				}
				sw.Cases.Add(defStat);
				con.Statements.Add(sw);
			}
			else
			{
				CodeScopeStatement tCont = new CodeScopeStatement();
				CodeScopeStatement fCont = new CodeScopeStatement();
				CodeExpression condition = Conditions[0].GetConditionExpression(this, overridenForm);
				for (int i = 1; i < Conditions.Count; i++)
				{
					condition = new CodeBinaryOperatorExpression(
						condition, 
						CodeBinaryOperatorType.BooleanAnd, 
						Conditions[i].GetConditionExpression(this, overridenForm)
					);
				}
				CodeConditionStatement condStat = new CodeConditionStatement(condition, new CodeStatement[] { tCont });
				NewForm.WriteEmit(tCont, true);
				if (!ignoreOtherOverrides)
				{
					condStat.FalseStatements.Add(fCont);
					if (overridenForm.Overrides.Count > 1)
					{
						// If we've gotten here, we know that we are the override at index 0.
						for (int i = 1; i < overridenForm.Overrides.Count; i++)
						{
							CodeScopeStatement eICont = new CodeScopeStatement();
							overridenForm.Overrides[i].WriteConditionalEmit(eICont, overridenForm, true);
							fCont.Statements.Add(eICont);
							fCont = new CodeScopeStatement();
							((CodeConditionStatement)eICont.Statements[0]).FalseStatements.Add(fCont);
						}
					}
					overridenForm.WriteEmit(fCont, true);
				}
				con.Statements.Add(condStat);
			}
		}
		public void Remove(CodeCaseStatement value)
		{
			base.List.Remove(value);
		}
		public void Insert(int index, CodeCaseStatement value)
		{
			base.List.Insert(index, value);
		}
		public int IndexOf(CodeCaseStatement value)
		{
			return base.List.IndexOf(value);
		}
		public void CopyTo(CodeCaseStatement[] array, int index)
		{
			base.List.CopyTo(array, index);
		}
		public bool Contains(CodeCaseStatement value)
		{
			return base.List.Contains(value);
		}
		public int Add(CodeCaseStatement value)
		{
			return base.List.Add(value);
		}
		public CodeCaseStatementCollection(CodeCaseStatement[] value)
		{
			this.AddRange(value);
		}
Beispiel #11
0
		public void Write(string outDir, CodeNamespace nmspc)
		{
			ExpandForms();
			EvaluateOverrides();
			bool lonely = FinalForms.Count == 1;
			CodeTypeDeclaration td = new CodeTypeDeclaration(FileName);
			td.Attributes = MemberAttributes.Final;
			td.Attributes |= MemberAttributes.Public;
			td.IsClass = true;
			td.BaseTypes.Add(StaticTypeReferences.Instruction);
			td.Documentation.Add(new CodeDocumentationSummaryNode(LinesOfDocumentation));

			foreach (InstructionForm f in FinalForms)
			{
				f.RequestFields();
			}
			foreach (var v in FieldDeclarations)
			{
				td.Members.Add(v);
			}

			foreach (InstructionForm f in FinalForms)
			{
				f.WriteConstructors(td, FileName);
			}

			CodeMemberMethod mth = new CodeMemberMethod();
			mth.Documentation.AddRange(
				new CodeDocumentationSummaryNode("Write this instruction to a stream."),
				new CodeDocumentationParameterNode(StaticTypeReferences.Emit_StreamArgName, "The stream to write to.")
			);
			mth.Name = "Emit";
			mth.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.Stream, StaticTypeReferences.Emit_StreamArgName));
			mth.Attributes = MemberAttributes.Public;
			mth.Attributes |= MemberAttributes.Override;
			mth.Attributes |= MemberAttributes.Sealed;
			mth.ReturnType = StaticTypeReferences.Void;
			CodeSwitchStatement instructionFormSwitch = null;
			if (!lonely)
			{
				instructionFormSwitch = new CodeSwitchStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "InstructionForm"));
				mth.Statements.Add(instructionFormSwitch);
			}
			foreach (InstructionForm f in FinalForms)
			{
				if (NeedsEmission(f))
				{
					CodeScopeStatement con = new CodeScopeStatement();
					if (lonely)
					{
						mth.Statements.Add(con);
					}
					else
					{
						CodeCaseStatement cas = new CodeCaseStatement(
							new CodeFieldReferenceExpression(StaticTypeReferences.InstructionFormExpression, f.GetInstructionCaseString())
						);
						cas.Statements.Add(con);
						cas.Statements.Add(new CodeBreakStatement());
						instructionFormSwitch.Cases.Add(cas);
					}
					f.WriteEmit(con, false);
				}
			}
			if (!lonely)
			{
				CodeDefaultCaseStatement defStat = new CodeDefaultCaseStatement();
				defStat.Statements.Add(
					new CodeThrowExceptionStatement(
						new CodeObjectCreateExpression(
							StaticTypeReferences.Exception,
							new CodePrimitiveExpression("Unknown Instruction Form!")
						)
					)
				);
				instructionFormSwitch.Cases.Add(defStat);
			}
			td.Members.Add(mth);
			instructionFormSwitch = null;

			FormsEmitted = new Dictionary<InstructionArgSet, bool>();

			mth = new CodeMemberMethod();
			bool hasSyntax = StaticTypeReferences.AssemblySyntaxClassName != null;
			if (hasSyntax)
			{
				mth.Documentation.AddRange(
					new CodeDocumentationSummaryNode(
						"Get a string representation of this instruction in the",
						"specified assembly syntax."
					),
					new CodeDocumentationParameterNode(StaticTypeReferences.ToString_SyntaxArgName, "The syntax to get the string representation in.")
				);
			}
			else
			{
				mth.Documentation.Add(new CodeDocumentationSummaryNode("Get a string representation of this instruction."));
			}
			mth.Name = "ToString";
			mth.Attributes = MemberAttributes.Public;
			mth.Attributes |= MemberAttributes.Override;
			mth.Attributes |= MemberAttributes.Sealed;
			mth.ReturnType = StaticTypeReferences.String;
			if (!hasSyntax)
			{
				if (!lonely)
				{
					instructionFormSwitch = new CodeSwitchStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "InstructionForm"));
					mth.Statements.Add(instructionFormSwitch);
				}
				foreach (InstructionForm f in FinalForms)
				{
					if (NeedsEmission(f))
					{
						CodeScopeStatement con = new CodeScopeStatement();
						if (lonely)
						{
							mth.Statements.Add(con);
						}
						else
						{
							CodeCaseStatement cas = new CodeCaseStatement(
								new CodeFieldReferenceExpression(
									StaticTypeReferences.InstructionFormExpression, 
									f.GetInstructionCaseString()
								)
							);
							cas.Statements.Add(con);
							instructionFormSwitch.Cases.Add(cas);
						}
						f.WriteToString(con);
					}
				}
				if (!lonely)
				{
					CodeDefaultCaseStatement defStat = new CodeDefaultCaseStatement();
					defStat.Statements.Add(
						new CodeThrowExceptionStatement(
							new CodeObjectCreateExpression(
								StaticTypeReferences.Exception,
								new CodePrimitiveExpression("Unknown Instruction Form!")
							)
						)
					);
					instructionFormSwitch.Cases.Add(defStat);
				}
			}
			else
			{
				mth.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.AssemblySyntax, StaticTypeReferences.ToString_SyntaxArgName));
				CodeSwitchStatement sw = new CodeSwitchStatement(StaticTypeReferences.ToString_SyntaxArg);
				mth.Statements.Add(sw);

				CodeCaseStatement cs = new CodeCaseStatement(
					new CodeFieldReferenceExpression(
						StaticTypeReferences.AssemblySyntaxExpression,
						"NASM"
					)
				);
				if (!lonely)
				{
					instructionFormSwitch = new CodeSwitchStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "InstructionForm"));
					cs.Statements.Add(instructionFormSwitch);
				}
				foreach (InstructionForm f in FinalForms)
				{
					if (NeedsEmission(f))
					{
						CodeScopeStatement con = new CodeScopeStatement();
						if (lonely)
						{
							cs.Statements.Add(con);
						}
						else
						{
							CodeCaseStatement cas = new CodeCaseStatement(
								new CodeFieldReferenceExpression(StaticTypeReferences.InstructionFormExpression, f.GetInstructionCaseString())
							);
							cas.Statements.Add(con);
							instructionFormSwitch.Cases.Add(cas);
						}
						f.WriteToString(con);
					}
				}
				if (!lonely)
				{
					CodeDefaultCaseStatement defStat = new CodeDefaultCaseStatement();
					defStat.Statements.Add(
						new CodeThrowExceptionStatement(
							new CodeObjectCreateExpression(
								StaticTypeReferences.Exception,
								new CodePrimitiveExpression("Unknown Instruction Form!")
							)
						)
					);
					instructionFormSwitch.Cases.Add(defStat);
				}
				sw.Cases.Add(cs);

				cs = new CodeCaseStatement(
					new CodeFieldReferenceExpression(
						StaticTypeReferences.AssemblySyntaxExpression,
						"GAS"
					)
				);
				sw.Cases.Add(cs);
				CodeDefaultCaseStatement def = new CodeDefaultCaseStatement();
				def.Statements.Add(
					new CodeThrowExceptionStatement(
						new CodeObjectCreateExpression(
							StaticTypeReferences.Exception,
							new CodePrimitiveExpression("Unknown Instruction Form!")
						)
					)
				);
				sw.Cases.Add(def);
			}

			td.Members.Add(mth);


			nmspc.Types.Add(td);
		}
		private void WriteConstructorBodyInstructionFormDetermination(CodeConstructor c, List<byte> sizesNeeded, List<string> formsNeeded)
		{
			if (sizesNeeded.Count > 1)
			{
				CodeSwitchStatement s = new CodeSwitchStatement(new CodeArgumentReferenceExpression("size"));

				// If your willing to accept the sizes being out of order, then this isn't
				// needed, but I don't like them out of order so it is.
				List<KeyValuePair<byte, string>> sizeFormPairs = new List<KeyValuePair<byte, string>>();
				for (int i = 0; i < sizesNeeded.Count; i++)
				{
					sizeFormPairs.Add(new KeyValuePair<byte, string>(sizesNeeded[i], formsNeeded[i]));
				}
				sizeFormPairs.Sort(
					delegate(KeyValuePair<byte, string> x, KeyValuePair<byte, string> y)
					{
						return x.Key.CompareTo(y.Key);
					}
				);
				sizesNeeded.Sort();
				for (int i = 0; i < sizeFormPairs.Count; i++)
				{
					// The cast is needed so it doesn't write the value out as hex.
					CodeCaseStatement cas = new CodeCaseStatement(new CodePrimitiveExpression((int)sizeFormPairs[i].Key));
					cas.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "InstructionForm"),
							new CodeFieldReferenceExpression(StaticTypeReferences.InstructionFormExpression, sizeFormPairs[i].Value)
						)
					);
					cas.Statements.Add(new CodeBreakStatement());
					s.Cases.Add(cas);
					InstructionFormEnumRegistry.RequestForm(sizeFormPairs[i].Value);
				}

				string exSzs = "";
				if (sizesNeeded.Count == 2)
				{
					exSzs = "either " + sizesNeeded[0].ToString() + " or " + sizesNeeded[1].ToString();
				}
				else
				{
					exSzs = sizesNeeded[0].ToString();
					int szndc = sizesNeeded.Count - 1;
					for (int i = 1; i < szndc; i++)
					{
						exSzs += ", " + sizesNeeded[i].ToString();
					}
					exSzs += " or " + sizesNeeded[szndc];
				}
				CodeDefaultCaseStatement defStat = new CodeDefaultCaseStatement();
				defStat.Statements.Add(
					new CodeThrowExceptionStatement(
						new CodeObjectCreateExpression(
							StaticTypeReferences.ArgumentOutOfRangeException, 
							new CodePrimitiveExpression("size"),
							new CodePrimitiveExpression("Invalid size! Expected " + exSzs + "!")
						)
					)
				);
				s.Cases.Add(defStat);

				c.Statements.Add(s);
			}
			else
			{
				if (ParentInstruction.FinalForms.Count > 1)
				{
					c.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "InstructionForm"),
							new CodeFieldReferenceExpression(StaticTypeReferences.InstructionFormExpression, GetInstructionCaseString())
						)
					);
					InstructionFormEnumRegistry.RequestForm(GetInstructionCaseString());
				}
			}
		}