public static void Reset()
		{
			StaticTypeReferences.SegmentLookup = new Dictionary<string, bool>(16) 
			{
				{ "NONE", true }
			};
			StaticTypeReferences.StreamClassName = null;
			StaticTypeReferences.Stream = null;
			StaticTypeReferences.StreamExpression = null;
			StaticTypeReferences.Stream_InSByteRange = null;
			StaticTypeReferences.Stream_InShortRange = null;
			
			StaticTypeReferences.AssemblerClassName = null;
			StaticTypeReferences.Assembler = null;
			StaticTypeReferences.AssemblerExpression = null;

			StaticTypeReferences.InstructionClassName = null;
			StaticTypeReferences.Instruction = null;
			StaticTypeReferences.InstructionExpression = null;

			StaticTypeReferences.PrefixClassName = null;
			StaticTypeReferences.Prefix = null;
			StaticTypeReferences.PrefixExpression = null;

			StaticTypeReferences.InstructionFormClassName = null;
			StaticTypeReferences.InstructionForm = null;
			StaticTypeReferences.InstructionFormExpression = null;

			StaticTypeReferences.AssemblySyntaxClassName = null;
			StaticTypeReferences.AssemblySyntax = null;
			StaticTypeReferences.AssemblySyntaxExpression = null;

			StaticTypeReferences.SegmentClassName = null;
			StaticTypeReferences.Segment = null;
			StaticTypeReferences.SegmentExpression = null;
		}
		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()
				);
			}
		}
		public static void InitializeTypes()
		{
			StaticTypeReferences.Stream = new CodeTypeReference(StreamClassName);
			StaticTypeReferences.StreamExpression = new CodeTypeReferenceExpression(Stream);
			StaticTypeReferences.Stream_InSByteRange = new CodeMethodReferenceExpression(StreamExpression, "InSByteRange");
			StaticTypeReferences.Stream_InShortRange = new CodeMethodReferenceExpression(StreamExpression, "InShortRange");

			StaticTypeReferences.Assembler = new CodeTypeReference(AssemblerClassName);
			StaticTypeReferences.AssemblerExpression = new CodeTypeReferenceExpression(Assembler);

			StaticTypeReferences.Instruction = new CodeTypeReference(InstructionClassName);
			StaticTypeReferences.InstructionExpression = new CodeTypeReferenceExpression(Instruction);

			StaticTypeReferences.Prefix = new CodeTypeReference(PrefixClassName);
			StaticTypeReferences.PrefixExpression = new CodeTypeReferenceExpression(Prefix);

			StaticTypeReferences.InstructionForm = new CodeTypeReference(InstructionFormClassName);
			StaticTypeReferences.InstructionFormExpression = new CodeTypeReferenceExpression(InstructionForm);

			if (AssemblySyntaxClassName != null)
			{
				StaticTypeReferences.AssemblySyntax = new CodeTypeReference(AssemblySyntaxClassName);
				StaticTypeReferences.AssemblySyntaxExpression = new CodeTypeReferenceExpression(AssemblySyntax);
			}


			StaticTypeReferences.Segment = new CodeTypeReference(SegmentClassName);
			StaticTypeReferences.SegmentExpression = new CodeTypeReferenceExpression(Segment);
			FieldTypeRegistry.Segment = FieldTypeRegistry.Fields[FieldTypeRegistry.RegisterType(SegmentClassName, "seg_")];
		}