public void Write(CodeScopeStatement con, InstructionForm ParentForm) { switch (Type) { case WriteOperationType.Arg: con.Statements.Add( ParentForm[ArgIdx].ArgType.WriteOperation.GetExpression(ParentForm, ArgIdx, this) ); break; case WriteOperationType.Prefix: con.Statements.Add( new CodeMethodInvokeExpression( StaticTypeReferences.Emit_Stream_WritePrefix, new CodeFieldReferenceExpression(StaticTypeReferences.PrefixExpression, SelectedPrefix) ) ); break; case WriteOperationType.Byte: con.Statements.Add( new CodeMethodInvokeExpression( StaticTypeReferences.Emit_Stream_WriteByte, new CodePrimitiveExpression(ByteValue) ) ); break; case WriteOperationType.BytePlusArg: con.Statements.Add( new CodeMethodInvokeExpression( StaticTypeReferences.Emit_Stream_WriteByte, new CodeCastExpression( StaticTypeReferences.Byte, new CodeBinaryOperatorExpression( new CodePrimitiveExpression(ByteValue), CodeBinaryOperatorType.Add, ParentForm[ArgIdx].ArgType.AsArgOperation.GetExpression(ParentForm, ArgIdx, this) ) ) ) ); break; case WriteOperationType.Imm8: con.Statements.Add( new CodeMethodInvokeExpression( StaticTypeReferences.Emit_Stream_WriteImm8, new CodeCastExpression( StaticTypeReferences.Byte, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), ParentForm.GetArgName(FieldTypeRegistry.UInt.ID, 1, ArgIdx) ) ) ) ); break; case WriteOperationType.Imm16: con.Statements.Add( new CodeMethodInvokeExpression( StaticTypeReferences.Emit_Stream_WriteImm16, new CodeCastExpression( StaticTypeReferences.UShort, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), ParentForm.GetArgName(FieldTypeRegistry.UInt.ID, 1, ArgIdx) ) ) ) ); break; case WriteOperationType.Imm32: con.Statements.Add( new CodeMethodInvokeExpression( StaticTypeReferences.Emit_Stream_WriteImm32, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), ParentForm.GetArgName(FieldTypeRegistry.UInt.ID, 1, ArgIdx) ) ) ); break; case WriteOperationType.Throw: con.Statements.Add( new CodeThrowExceptionStatement( new CodeObjectCreateExpression( StaticTypeReferences.Exception, new CodePrimitiveExpression(MessageThrown) ) ) ); break; default: throw new Exception("Unsupported write operation type!"); } }
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 WriteToString(CodeScopeStatement con) { if (Arg1.ArgType == InstructionArgType.None) { con.Statements.Add( new CodeMethodReturnStatement( new CodePrimitiveExpression(Mnemonic) ) ); } else if (Arg2.ArgType == InstructionArgType.None) { if (ExcludeCondition != null) { CodeConditionStatement f = new CodeConditionStatement(ExcludeCondition.GetConditionExpression(this)); f.TrueStatements.Add( new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodePrimitiveExpression(Mnemonic + " "), CodeBinaryOperatorType.StringConcat, Arg1.ArgType.GetToStringForArg(this, 0) ) ) ); f.FalseStatements.Add( new CodeMethodReturnStatement( new CodePrimitiveExpression(Mnemonic) ) ); con.Statements.Add(f); } else { con.Statements.Add( new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodePrimitiveExpression(Mnemonic + " "), CodeBinaryOperatorType.StringConcat, Arg1.ArgType.GetToStringForArg(this, 0) ) ) ); } } else if (Arg3.ArgType == InstructionArgType.None) { con.Statements.Add( new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodePrimitiveExpression(Mnemonic + " "), CodeBinaryOperatorType.StringConcat, new CodeBinaryOperatorExpression( Arg1.ArgType.GetToStringForArg(this, 0), CodeBinaryOperatorType.StringConcat, new CodeBinaryOperatorExpression( new CodePrimitiveExpression(", "), CodeBinaryOperatorType.StringConcat, Arg2.ArgType.GetToStringForArg(this, 1) ) ) ) ) ); } else { con.Statements.Add( new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodePrimitiveExpression(Mnemonic + " "), CodeBinaryOperatorType.StringConcat, new CodeBinaryOperatorExpression( Arg1.ArgType.GetToStringForArg(this, 0), CodeBinaryOperatorType.StringConcat, new CodeBinaryOperatorExpression( new CodeBinaryOperatorExpression( new CodePrimitiveExpression(", "), CodeBinaryOperatorType.StringConcat, Arg2.ArgType.GetToStringForArg(this, 1) ), CodeBinaryOperatorType.StringConcat, new CodeBinaryOperatorExpression( new CodePrimitiveExpression(", "), CodeBinaryOperatorType.StringConcat, Arg3.ArgType.GetToStringForArg(this, 2) ) ) ) ) ) ); } }
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); }
public void WriteEmit(CodeScopeStatement con, bool ignoreOverrides/* = false*/) { if (!ignoreOverrides && Overrides.Count > 0) { Overrides[0].WriteConditionalEmit(con, this); } else { int segArgIdx; if (NeedsSegment(out segArgIdx)) { con.Statements.Add( new CodeMethodInvokeExpression( StaticTypeReferences.Emit_Stream_WriteSegmentOverride, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), GetArgName(FieldTypeRegistry.Segment.ID, 1, segArgIdx) ), new CodeFieldReferenceExpression(StaticTypeReferences.SegmentExpression, DefaultSegment) ) ); } for (int i = 0; i < WriteOperations.Count; i++) { WriteOperations[i].Write(con, this); } } }