protected override void GenerateConstructor(CodeConstructor constructor, CodeTypeDeclaration declaration) { if (base.IsCurrentDelegate || base.IsCurrentEnum || base.IsCurrentInterface) { return; } this.OutputMemberAccessModifier(constructor.Attributes); base.Output.Write("this("); this.OutputParameters(constructor.Parameters); base.Output.Write(")"); base.OutputStartBrace(); base.Indent++; if (constructor.BaseConstructorArgs.Count > 0) { base.Output.Write("super("); this.OutputExpressionList(constructor.BaseConstructorArgs); base.Output.WriteLine(");"); } if (constructor.ChainedConstructorArgs.Count > 0) { base.Output.Write("this("); this.OutputExpressionList(constructor.ChainedConstructorArgs); base.Output.WriteLine(");"); } base.GenerateStatements(constructor.Statements); base.Indent--; base.Output.WriteLine('}'); }
public void WriteConstructors(CodeTypeDeclaration tdecl, string className) { if (ParentInstruction.LinesOfDocumentation.Count == 0) { ParentInstruction.LinesOfDocumentation.Add("Creates a new instance of the <see cref=\"" + ParentInstruction.FileName + "\" /> class."); } if (Arg1.ArgType == InstructionArgType.None) { CodeConstructor c = new CodeConstructor(); c.Attributes = MemberAttributes.Public; c.Documentation.AddRange( new CodeDocumentationSummaryNode(ParentInstruction.LinesOfDocumentation), new CodeDocumentationParameterNode("parentAssembler", "The assembler to add this instruction to.") ); c.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.Assembler, "parentAssembler")); c.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("parentAssembler")); tdecl.Members.Add(c); } else { List<byte> sizesNeeded = new List<byte>(4); List<string> formsNeeded = new List<string>(4); bool constructorNeeded; bool needsSizeArg = ParentInstruction.NeedsSizeArgument(Arg1.ArgType, Arg2.ArgType, Arg3.ArgType, ref sizesNeeded, out constructorNeeded, ref formsNeeded); if (constructorNeeded) { int segArgIdx; bool needsSegArg = NeedsSegment(out segArgIdx); CodeConstructor c = new CodeConstructor(); c.Attributes = MemberAttributes.Public; c.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.Assembler, "parentAssembler")); c.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("parentAssembler")); Arg1.ArgType.RequestParameters(Arg1, needsSizeArg, c.Parameters); Arg2.ArgType.RequestParameters(Arg2, needsSizeArg, c.Parameters); Arg3.ArgType.RequestParameters(Arg3, needsSizeArg, c.Parameters); if (needsSizeArg) c.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.Byte, "size")); if (needsSegArg) { CodeParameterDeclarationExpression cpd = new CodeParameterDeclarationExpression(StaticTypeReferences.Segment, "segment"); cpd.DefaultValueExpression = new CodeFieldReferenceExpression(StaticTypeReferences.SegmentExpression, DefaultSegment.ToString()); c.Parameters.Add(cpd); } CodeDocumentationNodeCollection docs = new CodeDocumentationNodeCollection(); docs.Add(new CodeDocumentationParameterNode("parentAssembler", "The assembler to add this instruction to.")); Arg1.ArgType.AddDocumentationLines(Arg1.Name, docs); Arg2.ArgType.AddDocumentationLines(Arg2.Name, docs); Arg3.ArgType.AddDocumentationLines(Arg3.Name, docs); if (needsSizeArg) docs.Add(new CodeDocumentationParameterNode("size", "The size of the operands for this instruction.")); if (needsSegArg) docs.Add(new CodeDocumentationParameterNode("segment", "The segment to use for memory access within this instruction.")); c.Documentation.Add(new CodeDocumentationSummaryNode(ParentInstruction.LinesOfDocumentation)); c.Documentation.AddRange(docs); WriteConstructorBodyInstructionFormDetermination(c, sizesNeeded, formsNeeded); Arg1.ArgType.WriteConstructorBodyArgProcessing(this, c, 0); Arg2.ArgType.WriteConstructorBodyArgProcessing(this, c, 1); Arg3.ArgType.WriteConstructorBodyArgProcessing(this, c, 2); if (needsSegArg) { c.Statements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), GetArgName(FieldTypeRegistry.Segment.ID, 1, segArgIdx)), new CodeArgumentReferenceExpression("segment") ) ); } tdecl.Members.Add(c); } } }
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()); } } }
public void WriteConstructorBodyArgProcessing(InstructionForm frm, CodeConstructor c, int argIdx) { InstructionArg arg = frm[argIdx]; switch (ID) { case None_ID: break; // Dis8 & Dis16 have to be sign-extended before being stored. // (this way they can be compared using the exact same code as // dis32 can) case Dis8_ID: case Dis16_ID: c.Statements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx) ), new CodeCastExpression( StaticTypeReferences.UInt, new CodeCastExpression( StaticTypeReferences.Int, new CodeArgumentReferenceExpression(arg.Name + DisArgSuffix) ) ) ) ); break; // No sign extension needed. case Dis32_ID: c.Statements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx) ), new CodeCastExpression( StaticTypeReferences.UInt, new CodeArgumentReferenceExpression(arg.Name + DisArgSuffix) ) ) ); break; case Imm8_ID: case Imm16_ID: case Imm32_ID: c.Statements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx) ), new CodeCastExpression( StaticTypeReferences.UInt, new CodeArgumentReferenceExpression(arg.Name + ImmArgSuffix) ) ) ); break; default: int[] reqs = new int[FieldTypeRegistry.MaxFieldID + 1]; foreach(CustomInstructionArgParameter p in mParameters.Values) { c.Statements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(p.ArgType, reqs[p.ArgType] + 1, argIdx) ), new CodeArgumentReferenceExpression(arg.Name + p.ArgNameSuffix) ) ); reqs[p.ArgType]++; } break; } }