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