public override int Compile(FunctionContext context) { context.Line(FileName, Line); var isStatement = Parent is IBlockStatementExpression; if (Name == null && isStatement) throw new MondCompilerException(FileName, Line, "Function is never used"); IdentifierOperand identifier = null; if (Name != null) { if (!context.DefineIdentifier(Name, true)) throw new MondCompilerException(FileName, Line, "Identifier '{0}' was previously defined in this scope", Name); identifier = context.Identifier(Name); } var functionContext = context.MakeFunction(Name); functionContext.Function(FileName, Name); context.PushFrame(); for (var i = 0; i < Arguments.Count; i++) { var name = Arguments[i]; if (!functionContext.DefineArgument(i, name)) throw new MondCompilerException(FileName, Line, "Identifier '{0}' was previously defined in this scope", name); } functionContext.Bind(functionContext.Label); functionContext.Enter(); Block.Compile(functionContext); functionContext.LoadUndefined(); functionContext.Return(); context.PopFrame(); context.Closure(functionContext.Label); if (identifier != null) { if (!isStatement) // statements should leave nothing on the stack context.Dup(); context.Store(identifier); if (isStatement) return 0; } return 1; }