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); } }