public CodeExpression GetLoadExpression(InstructionForm frm, int argIdx) { int reqFldsPrev = 0; foreach (var val in Parent.Parameters.Values) { if (val == this) break; if (val.ArgType == this.ArgType) { reqFldsPrev++; } } return new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(ArgType, reqFldsPrev + 1, argIdx) ); }
public InstructionForm DeepCopy() { // Because of the way this is designed (awesomely in my opinion), // the only thing that has to be deep copied in the WriteOperation list. InstructionForm i = new InstructionForm(ParentInstruction); i.Arg1 = Arg1; i.Arg2 = Arg2; i.Arg3 = Arg3; i.Mnemonic = Mnemonic; i.DefaultSegment = DefaultSegment; i.ExcludeCondition = ExcludeCondition != null ? ExcludeCondition.DeepCopy() : null; foreach (WriteOperationArgument arg in WriteOperationArgs) { i.WriteOperationArgs.Add(arg.DeepCopy()); } i.WriteOperations.AddRange(WriteOperations); return i; }
public CodeExpression GetLoadExpression(InstructionForm frm) { if (Type == OperationSourceType.Constant) { return new CodePrimitiveExpression(Constant); } else { switch(frm[ParentArgIdx].ArgType.ID) { case InstructionArgType.Imm32_ID: return new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, ParentArgIdx) ); case InstructionArgType.Imm16_ID: return new CodeCastExpression( StaticTypeReferences.UShort, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, ParentArgIdx) ) ); case InstructionArgType.Imm8_ID: return new CodeCastExpression( StaticTypeReferences.Byte, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, ParentArgIdx) ) ); default: if (frm[ParentArgIdx].ArgType.AsArgOperation == null) throw new Exception("The specified arg isn't valid as an argument to a write operation!"); return frm[ParentArgIdx].ArgType.AsArgOperation.GetExpression(frm, ParentArgIdx, null); } } }
public CodeExpression GetConditionExpression(InstructionForm parent) { CodeBinaryOperatorType cond; switch (Condition) { case ConditionType.Less: cond = CodeBinaryOperatorType.LessThan; break; case ConditionType.LessOrEqual: cond = CodeBinaryOperatorType.LessThanOrEqual; break; case ConditionType.Greater: cond = CodeBinaryOperatorType.GreaterThan; break; case ConditionType.GreaterOrEqual: cond = CodeBinaryOperatorType.GreaterThanOrEqual; break; case ConditionType.Equal: cond = CodeBinaryOperatorType.ValueEquality; break; case ConditionType.NotEqual: cond = CodeBinaryOperatorType.IdentityInequality; break; default: throw new Exception("Unknown condition!"); } return new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), parent.GetArgName(FieldTypeRegistry.UInt.ID, 1, ArgToExclude) ), cond, new CodePrimitiveExpression(ConditionArg) ); }
public WriteOperation(Token[] toks, InstructionForm ParentForm) { // As a note, all operations should be 4 characters, // if they are unable to be 4 characters, then they // should be sets of 4 characters seperated in // some way. (this allows for the write operations to // be aligned in the cpud file) Token tok = toks[0]; switch (toks.Length) { case 1: if (tok.Type == TokenType.Number) { this.Type = WriteOperationType.Byte; this.ByteValue = (byte)tok.NumberValue.Value; } else if (tok.Value.StartsWith("arg")) { this.ArgIdx = (byte)(Utils.SingleDigitParse(tok.Value[3]) - 1); if (!ParentForm[ArgIdx].ArgType.HasSize) { this.Type = WriteOperationType.Arg; } else { switch(ParentForm[ArgIdx].ArgType.Size) { case 1: this.Type = WriteOperationType.Imm8; break; case 2: this.Type = WriteOperationType.Imm16; break; case 4: this.Type = WriteOperationType.Imm32; break; default: throw new Exception("Unknown arg type!"); } } } else // Prefix { this.Type = WriteOperationType.Prefix; this.SelectedPrefix = PrefixRegistry.GetPrefixName(tok.Value); if (this.SelectedPrefix == null) throw new Exception("Unknown write operation '" + tok.Value + "'!"); } break; case 3: this.Type = WriteOperationType.BytePlusArg; this.ArgIdx = (byte)(Utils.SingleDigitParse(toks[2].Value[3]) - 1); this.ByteValue = (byte)tok.NumberValue.Value; break; case 4: if (tok.Value == "evil") { if (toks[1].Type != TokenType.LSqBracket) throw new Exception("Expected an opening square bracket before the exception's message!"); if (toks[3].Type != TokenType.RSqBracket) throw new Exception("Expected the closing square bracket after the exception's message!"); this.Type = WriteOperationType.Throw; this.MessageThrown = toks[2].Value; } else if (tok.Value.StartsWith("arg")) { if (toks[1].Type != TokenType.LSqBracket) throw new Exception("Expected an opening square bracket before the argument write operation!"); if (toks[3].Type != TokenType.RSqBracket) throw new Exception("Expected the closing square bracket after the argument write operation!"); this.ArgIdx = (byte)(Utils.SingleDigitParse(tok.Value[3]) - 1); this.Type = WriteOperationType.Arg; this.WriteArguments.Add(new WriteOperationArgument(toks[2])); } else { throw new Exception("Unknown write operation type!"); } break; default: if (tok.Value.StartsWith("arg")) { if (toks[1].Type != TokenType.LSqBracket) throw new Exception("Expected an opening square bracket before the argument write operation!"); this.Type = WriteOperationType.Arg; this.ArgIdx = (byte)(Utils.SingleDigitParse(tok.Value[3]) - 1); for (int i = 2; i < toks.Length - 1; i += 2) { this.WriteArguments.Add(new WriteOperationArgument(toks[i])); if (i + 1 < toks.Length - 1 && toks[i + 1].Type != TokenType.Comma) throw new Exception("Expected a comma!"); } if (toks[toks.Length - 1].Type != TokenType.RSqBracket) throw new Exception("Expected the closing square bracket after the argument write operation!"); } else { throw new Exception("Unknown number of tokens passed in!"); } break; } }
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 CodeExpression GetConditionExpression(InExactInstructionOverrideDescription ParentDesc, InstructionForm formOverriding) { switch (Condition) { case ConditionType.Fits: switch(ParentDesc.NewForm[ArgIndexToCheck].ArgType.ID) { case InstructionArgType.Dis8_ID: case InstructionArgType.Imm8_ID: return new CodeMethodInvokeExpression( StaticTypeReferences.Stream_InSByteRange, new CodeCastExpression( StaticTypeReferences.Int, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), formOverriding.GetArgName(FieldTypeRegistry.UInt.ID, 1, ArgIndexToCheck) ) ) ); case InstructionArgType.Dis16_ID: case InstructionArgType.Imm16_ID: return new CodeMethodInvokeExpression( StaticTypeReferences.Stream_InShortRange, new CodeCastExpression( StaticTypeReferences.Int, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), formOverriding.GetArgName(FieldTypeRegistry.UInt.ID, 1, ArgIndexToCheck) ) ) ); default: throw new Exception("Unknown arg type!"); } case ConditionType.Compare_Imm: if (ParentDesc.NewForm[ArgIndexToCheck].ArgType == InstructionArgType.Imm8) { return new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), formOverriding.GetArgName(FieldTypeRegistry.UInt.ID, 1, ArgIndexToCheck) ), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(ImmValueToCompareTo) ); } else { return new CodeBinaryOperatorExpression( ParentDesc.NewForm[ArgIndexToCheck].ArgType.AsArgOperation.GetExpression(ParentDesc.NewForm, ArgIndexToCheck, null), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(ImmValueToCompareTo) ); } case ConditionType.Compare_Reg: // Yikes.... var enu = formOverriding[ArgIndexToCheck].ArgType.Parameters.Values.GetEnumerator(); enu.MoveNext(); int argType = enu.Current.ArgType; return new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), formOverriding.GetArgName(argType, 1, ArgIndexToCheck) ), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(FieldTypeRegistry.Fields[argType].Name), RegisterToCompareTo ) ); case ConditionType.Compare_Segment: return new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), formOverriding.GetArgName(FieldTypeRegistry.Segment.ID, 1, ArgIndexToCheck) ), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(StaticTypeReferences.SegmentExpression, RegisterToCompareTo) ); default: throw new Exception("Unknown Condition!"); } }
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); } }
private bool CanGenSegmentSwitch(InstructionForm overridenForm) { if (overridenForm.Overrides.Count < 2) return false; for (int i = 0; i < overridenForm.Overrides.Count; i++) { var l = overridenForm.Overrides[i].Conditions; for (int i2 = 0; i2 < l.Count; i2++) { if (l[i2].Condition != OverrideCondition.ConditionType.Compare_Segment) return false; } } return true; }
public bool NeedsEmission(InstructionForm frm) { InstructionArgSet key = new InstructionArgSet() { Arg1 = InstructionArgTypeRegistry.GetType(frm.Arg1.ArgType.TrueName), Arg2 = InstructionArgTypeRegistry.GetType(frm.Arg2.ArgType.TrueName), Arg3 = InstructionArgTypeRegistry.GetType(frm.Arg3.ArgType.TrueName) }; if (!FormsEmitted.ContainsKey(key)) { FormsEmitted[key] = true; return true; } return false; }
private void ExpandSingleForm(InstructionForm f, int argIdx) { foreach (InstructionArgType tp in f[argIdx].ArgType.ExpandsTo) { InstructionForm f2 = f.DeepCopy(); InstructionArg a = f2[argIdx]; a.ArgType = tp; f2[argIdx] = a; FinalForms.Add(f2); } }
public CodeExpression GetToStringForArg(InstructionForm frm, int argIdx) { InstructionArg arg = frm[argIdx]; int padSize = 0; switch (arg.ArgType.ID) { case InstructionArgType.Dis8_ID: case InstructionArgType.Dis16_ID: case InstructionArgType.Dis32_ID: return new CodeMethodInvokeExpression( StaticTypeReferences.NamingHelper_NameDisplacement, StaticTypeReferences.ParentAssemblerExpression, new CodeThisReferenceExpression(), new CodeCastExpression( StaticTypeReferences.Int, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx) ) ) ); case InstructionArgType.Imm8_ID: padSize = 2; goto ImmCommon; case InstructionArgType.Imm16_ID: padSize = 4; goto ImmCommon; case InstructionArgType.Imm32_ID: padSize = 8; goto ImmCommon; default: return arg.ArgType.ReadOperation.GetExpression(frm, argIdx, null); } ImmCommon: if (arg.NumberFormat == ImmNumberFormat.Decimal) { return new CodeMethodInvokeExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx) ), "ToString" ); } else { return Generator.LanguageProvider.GetPaddedHexToString( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx) ), padSize ); } }
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; } }
public CodeExpression GetExpression(InstructionForm frm, int argIdx, WriteOperation wrOp) { int curIdx = 0; Token tok = toks[curIdx]; if (tok.Type != TokenType.Identifier) throw new Exception("Expected an identifier!"); if (tok.Value == "ToString") { curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.LParen) throw new Exception("Expected an opening parenthesis!"); curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.Identifier) throw new Exception("Expected an identifier for the expression to convert to a string!"); CodeExpression ldExpr = GetExpressionFromIdentifier(tok.Value, frm, argIdx, wrOp); curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.RParen) throw new Exception("Expected the closing parenthesis!"); curIdx++; return new CodeMethodInvokeExpression( ldExpr, "ToString" ); } else if (tok.Value == "DirectCast") { curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.LParen) throw new Exception("Expected an opening parenthesis!"); curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.Identifier) throw new Exception("Expected an identifier representing the argument to cast!"); CustomInstructionArgParameter param; if (!ParentArg.Parameters.TryGetValue(tok.Value, out param)) throw new Exception("Unknown parameter '" + tok.Value + "'!"); CodeExpression argLoadExpression = param.GetLoadExpression(frm, argIdx); curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.Comma) throw new Exception("Expected a comma before the destination type!"); curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.Identifier) throw new Exception("Expected an identifier representing the type to cast to!"); CodeTypeReference destType; switch(tok.Value.ToLower()) { case "byte": destType = StaticTypeReferences.Byte; break; case "sbyte": destType = StaticTypeReferences.SByte; break; case "ushort": destType = StaticTypeReferences.UShort; break; case "short": destType = StaticTypeReferences.Short; break; case "uint": destType = StaticTypeReferences.UInt; break; case "int": destType = StaticTypeReferences.Int; break; case "ulong": destType = StaticTypeReferences.ULong; break; case "long": destType = StaticTypeReferences.Long; break; default: destType = new CodeTypeReference(tok.Value); break; } curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.RParen) throw new Exception("Expected closing parenthesis!"); curIdx++; return new CodeCastExpression( destType, argLoadExpression ); } else { CodeExpression sourceExpression; bool NamedArgNeedsCast = false; if (tok.Value == "Stream") { sourceExpression = StaticTypeReferences.Emit_StreamArg; } else { if (tok.Value == "BitPatterns") NamedArgNeedsCast = true; sourceExpression = new CodeTypeReferenceExpression(tok.Value); } curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.Dot) throw new Exception("Expected a dot!"); curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.Identifier) throw new Exception("Expected an identifier!"); CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression( sourceExpression, NamedArgNeedsCast ? BitPatternRegistry.GetPattern(tok.Value).Name : tok.Value ); curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.LParen) throw new Exception("Expected an opening parenthesis!"); curIdx++; List<CodeExpression> parms = new List<CodeExpression>(8); tok = toks[curIdx]; bool expectsAnotherArg = true; while (tok.Type != TokenType.RParen) { if (!expectsAnotherArg) throw new Exception("Didn't expect another arg!"); switch (tok.Type) { case TokenType.Identifier: parms.Add(GetExpressionFromIdentifier(tok.Value, frm, argIdx, wrOp, NamedArgNeedsCast)); break; case TokenType.Number: if (tok.NumberValue.Format == NumberFormat.Decimal) { parms.Add(new CodePrimitiveExpression((int)tok.NumberValue.Value)); } else { parms.Add(new CodePrimitiveExpression(tok.NumberValue.Value)); } break; default: throw new Exception("Unknown token type!"); } curIdx++; tok = toks[curIdx]; if (tok.Type != TokenType.Comma) { expectsAnotherArg = false; } else { curIdx++; tok = toks[curIdx]; } } if (expectsAnotherArg) throw new Exception("Expected another arg!"); return new CodeMethodInvokeExpression( methodRef, parms.ToArray() ); } }
private CodeExpression GetExpressionFromIdentifier(string val, InstructionForm frm, int argIdx, WriteOperation wrOp, bool namedParamNeedsCast = false) { CustomInstructionArgParameter param; if (ParentArg.Parameters.TryGetValue(val, out param)) { if (namedParamNeedsCast) { return frm[argIdx].ArgType.AsArgOperation.GetExpression(frm, argIdx, wrOp); } else { return param.GetLoadExpression(frm, argIdx); } } else if (val == "Segment") { return new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), frm.GetArgName(FieldTypeRegistry.Segment.ID, 1, InstructionArgSet.TotalArgs_Max) ); } else if (val == "ParentAssembler") { return StaticTypeReferences.ParentAssemblerExpression; } else if (val == "Stream") { return StaticTypeReferences.Emit_StreamArg; } else if (val.StartsWith("arg")) { int fArg = Utils.SingleDigitParse(val[3]) - 1; return wrOp.WriteArguments[fArg].GetLoadExpression(frm); } else { return new CodeTypeReferenceExpression(val); } }