Esempio n. 1
0
		internal static int LoadFunction(Script script, SourceCode source, ByteCode bytecode, bool usesGlobalEnv)
		{
			ScriptLoadingContext lcontext = CreateLoadingContext(script, source);

			try
			{
				FunctionDefinitionExpression fnx;

				using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation))
					fnx = new FunctionDefinitionExpression(lcontext, usesGlobalEnv);

				int beginIp = -1;

				//var srcref = new SourceRef(source.SourceID);

				using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation))
				using (bytecode.EnterSource(null))
				{
					bytecode.Emit_Nop(string.Format("Begin function {0}", source.Name));
					beginIp = fnx.CompileBody(bytecode, source.Name);
					bytecode.Emit_Nop(string.Format("End function {0}", source.Name));
				}

				//Debug_DumpByteCode(bytecode, source.SourceID);

				return beginIp;
			}
			catch (SyntaxErrorException ex)
			{
				ex.DecorateMessage(script);
				throw;
			}

		}
		public FunctionDefinitionStatement(ScriptLoadingContext lcontext, bool local, Token localToken)
			: base(lcontext)
		{
			// here lexer must be at the 'function' keyword
			Token funcKeyword = CheckTokenType(lcontext, TokenType.Function);
			funcKeyword = localToken ?? funcKeyword; // for debugger purposes
			
			m_Local = local;

			if (m_Local)
			{
				Token name = CheckTokenType(lcontext, TokenType.Name);
				m_FuncSymbol = lcontext.Scope.TryDefineLocal(name.Text);
				m_FriendlyName = string.Format("{0} (local)", name.Text);
				m_SourceRef = funcKeyword.GetSourceRef(name);
			}
			else
			{
				Token name = CheckTokenType(lcontext, TokenType.Name);
				string firstName = name.Text;

				m_SourceRef = funcKeyword.GetSourceRef(name);

				m_FuncSymbol = lcontext.Scope.Find(firstName);
				m_FriendlyName = firstName;

				if (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round)
				{
					m_TableAccessors = new List<string>();

					while (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round)
					{
						Token separator = lcontext.Lexer.Current;

						if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot)
							UnexpectedTokenType(separator);
						
						lcontext.Lexer.Next();

						Token field = CheckTokenType(lcontext, TokenType.Name);

						m_FriendlyName += separator.Text + field.Text;
						m_SourceRef = funcKeyword.GetSourceRef(field);

						if (separator.Type == TokenType.Colon)
						{
							m_MethodName = field.Text;
							m_IsMethodCallingConvention = true;
							break;
						}
						else
						{
							m_TableAccessors.Add(field.Text);
						}
					}

					if (m_MethodName == null && m_TableAccessors.Count > 0)
					{
						m_MethodName = m_TableAccessors[m_TableAccessors.Count - 1];
						m_TableAccessors.RemoveAt(m_TableAccessors.Count - 1);
					}
				}
			}

			m_FuncDef = new FunctionDefinitionExpression(lcontext, m_IsMethodCallingConvention, false);
			lcontext.Source.Refs.Add(m_SourceRef);
		}